往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);
    posted @ 2012-10-09 22:17  CanMusic  阅读(1022)  评论(1编辑  收藏  举报