往USB端口设备写数据

  • Windows API
//获取某一类型的设备列表

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]

public static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPTStr)] string Enumerator, IntPtr hwndParent, UInt32 Flags);



//枚举设备

[DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]

public static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr hDevInfo, IntPtr devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);



//销毁设备列表

[DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]

public static extern bool SetupDiDestroyDeviceInfoList(IntPtr hDevInfo);



//获取某个设备的详细信息

[DllImport("setupapi.dll", CharSet = CharSet.Auto)]

private static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceIntefaceData, IntPtr DeviceInterfaceDetailData, int DeviceInterfacedetailDatasize, ref int DeviceInterfacedetaildataSize, IntPtr DeviceInfoData);



//打开读写端口

[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

public static extern IntPtr CreateFile(string fileName, [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess, [MarshalAs(UnmanagedType.U4)] FileShare fileShare, IntPtr securityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, int flags, IntPtr template);



//往端口写数据

[DllImport("kernel32.dll")]

public static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, [In] IntPtr lpOverlapped);



//关闭读写端口

[DllImport("kernel32.dll", SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool CloseHandle(IntPtr hObject);



[FlagsAttribute]

public enum DiGetClassFlags : uint {

    DIGCF_DEFAULT = 0x00000001,  // only valid with DIGCF_DEVICEINTERFACE

    DIGCF_PRESENT = 0x00000002,

    DIGCF_ALLCLASSES = 0x00000004,

    DIGCF_PROFILE = 0x00000008,

    DIGCF_DEVICEINTERFACE = 0x00000010,

}



[StructLayout(LayoutKind.Sequential)]

public struct SP_DEVINFO_DATA {

    public UInt32 cbSize;

    public Guid ClassGuid;

    public UInt32 DevInst;

    public IntPtr Reserved;

}



[StructLayout(LayoutKind.Sequential)]

public struct SP_DEVICE_INTERFACE_DATA {

    public UInt32 cbSize;

    public Guid InterfaceClassGuid;

    public UInt32 Flags;

    public UIntPtr Reserved;

}



[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

public struct SP_DEVICE_INTERFACE_DETAIL_DATA {

    public UInt32 cbSize;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

    public string DevicePath;

}
  • Open
  1. USB设备类的GUID为(a5dcbf10-6530-11d2-901f-00c04fb951ed)
  2. USB设备名称例如:(USB\VID_067B&PID_2305\6&2002C22&0&1)

     3. 获取某一设备类型的设备列表

Guid guid = new Guid("a5dcbf10-6530-11d2-901f-00c04fb951ed"); 

IntPtr hInfo = SetupDiGetClassDevs(ref guid, null, IntPtr.Zero, (uint)(DiGetClassFlags.DIGCF_PRESENT | DiGetClassFlags.DIGCF_DEVICEINTERFACE)); 

if(hInfo.ToInt32() == -1) { 

    return false; 

}

     4. 获取设备的读写路径

for(uint i = 0; i < 1000; ++i) { 

    SP_DEVICE_INTERFACE_DATA interface_Info = new SP_DEVICE_INTERFACE_DATA(); 

    interface_Info.cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA)); 

    if(!SetupDiEnumDeviceInterfaces(hInfo, IntPtr.Zero, ref guid, i, ref interface_Info)) { 

        SetupDiDestroyDeviceInfoList(hInfo); 

        break; 

    } 

    int needed = 0; 

    SetupDiGetDeviceInterfaceDetail(hInfo, ref interface_Info, IntPtr.Zero, 0, ref needed, IntPtr.Zero); 

    IntPtr detailDataBuffer; 

    detailDataBuffer = Marshal.AllocHGlobal(needed); 

    Marshal.WriteInt32(detailDataBuffer, 4 + Marshal.SystemDefaultCharSize); 

    if(!SetupDiGetDeviceInterfaceDetail(hInfo, ref interface_Info, detailDataBuffer, needed, ref needed, IntPtr.Zero)) { 

        SetupDiDestroyDeviceInfoList(hInfo); 

        return false; 

    } 

    SP_DEVICE_INTERFACE_DETAIL_DATA detail = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(detailDataBuffer, typeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); 

    if(detail.DevicePath.Contains(@"USB\VID_067B&PID_2305\6&2002C22&0&1")) { 

        name = detail.DevicePath; 

        break; 

    } 

}

      在这里name就是设备读写的路径。接着使用这个路径来打开读写端口即可。

handle = CreateFile(name, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero); 

if(handle.ToInt32() == -1) { 

    return false; 

}
    • Close
    CloseHandle(handle);
    • Write
    int tmp = 0; 
    
    bool result = WriteFile(handle, buf, buf.Length, out tmp, IntPtr.Zero);

    你可能感兴趣的:(数据)