2016-04-05 34 views
1

Ürün Dizesini, C# veya C++ üzerinde USB Aygıt Tanımlayıcısı'ndan (aygıt sabit sürücü değil, kulaklık gibi harici aygıt değil) nasıl edinebilirim? "My Headset" dizesini almam gerek.USB aygıtının ürün dizesini alın (C#/C++)

 ======================== USB Device ======================== 

     +++++++++++++++++ Device Information ++++++++++++++++++ 
Device Description  : USB Composite Device 
Device Path    : \\?\usb#vid_2ae2&pid_1388#abcdef#{a5dcbf10-6530-11d2-901f-00c04fb951ed} 
Device ID    : USB\VID_2AE2&PID_1388\ABCDEF
Driver KeyName   : {36fc9e60-c465-11cf-8056-444553540000}\0018 (GUID_DEVCLASS_USB) 
Driver     : C:\Windows\System32\drivers\usbccgp.sys (Version: 6.3.9600.17238 Date: 2014-07-24) 
Driver Inf    : C:\Windows\inf\usb.inf 
Legacy BusType   : PNPBus 
Class     : USB 
Service     : usbccgp 
Enumerator    : USB 
Location Info   : Port_#0006.Hub_#0003 
Location IDs    : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(6), ACPI(_SB_)#ACPI(PCI0)#ACPI(XHC_)#ACPI(RHUB)#ACPI(HS06) 
Container ID    : {acb9ebb8-b976-57c5-b90d-5ecc5e96e487} 
Manufacturer Info  : (Standard USB Host Controller) 
Capabilities    : 0x94 (Removable, UniqueID, SurpriseRemovalOK) 
Address     : 6 
Problem Code    : 0 
Power State    : D0 (supported: D0, D3, wake from D0) 
Child Device 1   : USB Input Device 
    Device ID    : USB\VID_2AE2&PID_1388&MI_03\6&12E75DA&0&0003 
    Class     : HIDClass 
    Child Device 1  : HID-compliant consumer control device 
    Device ID   : HID\VID_2AE2&PID_1388&MI_03\7&178A021A&0&0000 
    Class    : HIDClass 
Child Device 2   : USB Audio Device 
    Device ID    : USB\VID_2AE2&PID_1388&MI_00\6&12E75DA&0&0000 
    Class     : MEDIA 
    Child Device 1  : Audio Endpoint 
    Device ID   : SWD\MMDEVAPI\{0.0.1.00000000}.{0B0B6598-290C-495B-A4E1-D6A633F61574} 
    Class    : AudioEndpoint 
    Child Device 2  : Audio Endpoint 
    Device ID   : SWD\MMDEVAPI\{0.0.0.00000000}.{E3ADC851-586E-4FF8-BBF3-0EBF7E72FBDA} 
    Class    : AudioEndpoint 

     ------------------ Device Descriptor ------------------ 
bLength     : 0x12 (18 bytes) 
bDescriptorType   : 0x01 (Device Descriptor) 
bcdUSB     : 0x200 (USB Version 2.00) 
bDeviceClass    : 0x00 (defined by the interface descriptors) 
bDeviceSubClass   : 0x00 
bDeviceProtocol   : 0x00 
bMaxPacketSize0   : 0x40 (64 bytes) 
idVendor     : 0x2AE2 
idProduct    : 0x1388 
bcdDevice    : 0x1393 
iManufacturer   : 0x00 (No String Descriptor) 
iProduct     : 0x02 (String Descriptor 2) 
Language 0x0409   : "My Headset" 
iSerialNumber   : 0x03 (String Descriptor 3) 
Language 0x0409   : "ABCDEF" 
bNumConfigurations  : 0x01 

Şu anda, ben, göbeği açıp bu göbeğe bağlı Cihazımdan ürünü dizesini almak için IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION ile DeviceIoControl çağrı ürün dizesini almak için bu kod örneği kullanmak ama bu kod zaman zaman çalışır bazen göbek çünkü başkası ve CreateFile tarafından açılır (hubPath ..) başarısız:

// Open Hub 
IntPtr handle = CreateFile(hubPath, FileAccess.ReadWrite, FileShare.ReadWrite, 
    IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); 

if (handle.ToInt32() != INVALID_HANDLE_VALUE) 
{ 
    // 1. Load connection properties to get Device descriptor indexes 
    LogWriter.Debug("checking device, load hub connection properties..."); 

    USB_NODE_CONNECTION_INFORMATION_EX connectionInfo = new USB_NODE_CONNECTION_INFORMATION_EX(); 
    connectionInfo.ConnectionIndex = port; 

    // memset 
    string NullString = new string((char)0, nBytes/Marshal.SystemDefaultCharSize); 
    IntPtr connectionInfoBuffer = Marshal.StringToHGlobalAuto(NullString); 
    Marshal.StructureToPtr(connectionInfo, connectionInfoBuffer, true); 
    int iProductIndex = -1; 

    int ioBytes = Marshal.SizeOf(connectionInfo); 
    int nBytesReturned = 0; 

    if (DeviceIoControl(handle, 
     IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, 
     connectionInfoBuffer, 
     ioBytes, 
     connectionInfoBuffer, 
     ioBytes, 
     out nBytesReturned, 
     IntPtr.Zero) != 0) 
    { 
     LogWriter.Debug("checking device, hub connection properties loaded"); 

     USB_NODE_CONNECTION_INFORMATION_EX nodeConnection = (USB_NODE_CONNECTION_INFORMATION_EX)Marshal.PtrToStructure(connectionInfoBuffer, typeof(USB_NODE_CONNECTION_INFORMATION_EX)); 

     if (nodeConnection.DeviceIsHub == 0) 
     { 
      iProductIndex = nodeConnection.DeviceDescriptor.iProduct; 
      LogWriter.Debug(String.Format("GetDeviceProperties() Checking device, iProductIndex = {0}", iProductIndex)); 
     } 
    } 
    else 
    { 
     CheckError("DeviceIoControl"); 
    } 

    // 2. Load iProduct descriptor 
    USB_DESCRIPTOR_REQUEST stringDescReq = new USB_DESCRIPTOR_REQUEST(); 

    int bufSize = Marshal.SizeOf(stringDescReq) + MAXIMUM_USB_STRING_LENGTH; 

    stringDescReq.ConnectionIndex = port; 
    stringDescReq.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) | iProductIndex); 
    stringDescReq.SetupPacket.wIndex = 1033; // Language code 
    stringDescReq.SetupPacket.wLength = (short)(bufSize - Marshal.SizeOf(stringDescReq)); 

    // типа memset 
    IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString); 
    Marshal.StructureToPtr(stringDescReq, ptrRequest, true); 

    int nBytesRet = 0; 

    LogWriter.Debug(String.Format("checking device, load USB descriptor({0}, {1}, {2})", 
     stringDescReq.SetupPacket.wValue, 
     stringDescReq.SetupPacket.wIndex, 
     stringDescReq.SetupPacket.wLength)); 

    if (DeviceIoControl(handle, 
     IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, 
     ptrRequest, 
     bufSize, 
     ptrRequest, 
     bufSize, 
     out nBytesRet, 
     IntPtr.Zero) != 0) 
    { 
     int ptrSize = ptrRequest.ToInt32(); 

     LogWriter.Debug(String.Format("checking device, USB descriptor loaded({0}, {1})", 
      ptrSize, 
      Marshal.SizeOf(stringDescReq))); 

     IntPtr ptrStringDesc = new IntPtr(ptrSize + Marshal.SizeOf(stringDescReq)); 
     USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR)); 
     prop.ProductName = StringDesc.bString; 

     if (prop.ProductName != null) 
     { 
      LogWriter.Debug("ProductName = " + prop.ProductName); 
     } 
    } 
    else 
    { 
     LogWriter.Warn("DeviceIoControl failed"); 
     CheckError("DeviceIoControl"); 
    } 

    CloseHandle(handle); 
} 

yüzden istikrarlı çalışacak ürün dizesini almak için başka bir yola gerek. Bir not: geçerli cihaz HID'dir, bu yüzden HID işlevlerine izin verilecektir, ancak aynı zamanda HID olmayan USB aygıtlarım var ve çözüm HID ve HID olmayanlarla aynı şekilde çalışabilirse harika olur zaman. HidD_GetProductString rutin bir yıl önce denedim ve hatırladığım gibi boş arabelleği döndürdüğümde (sorun HID'nin çocuk aygıtları olduğu için yanlış aygıt yolu olabilir ve bu durumda sorun doğru aygıt yolunu elde etmektir). HID aygıtlarına gitmenin yolu

+0

' başarısız: Eğer HidLibrary kullanarak ve HidDevice _device var ediyorsanız, (üretici aynı şekilde çalışır) böyle bir ürün dize alabilirsiniz hub'ı doğrudan sorgulayamaz. Bu kadar basit. Eğer bilgi kayıt defterinde olduğu gibi başka bir yerde mevcut değilse, o zaman şansınız kalmaz. –

+0

Şunlara bir göz atın: http://stackoverflow.com/questions/3331043/get-list-of-connected-usb-devices – Gusman

+0

WMI'yi denedim ancak usb ürün dizesini geri göndermiyor (çok fazla orada sınıflar). – Evgeniy

cevap

0

. Daha önce her baytta \0 ile karşılaşmış olabilirsiniz. Eğer başkası, açık ve göbeği `CreateFile() varsa

byte[] bs; 
_device.ReadProduct(out bs); 
string ps = ""; 
foreach (byte b in bs) { 
    if (b > 0) 
     ps += ((char)b).ToString(); 
} 
+0

Diğer baytların 0 olmasının nedeni muhtemelen bir UTF-16 dizesi olmasıdır. Bu nedenle, ele alma yönteminiz ASCII olmayan dizeleri hatalı olarak ele alır. – rdb

İlgili konular