我想读取 USB 串行端口的设备描述符(不仅仅是 VID/PID——主要是这样我可以获得 bcdDevice、iProduct 和 iManufacturer),这样我就可以知道 USB 串行端口是否能够满足我的需求要做(我们在现场有几个调制解调器,其中一个在半双工时更可靠)。
我不想使用 libusbdotnet,因为我不希望我的用户必须提前弄清楚要过滤什么才能获得我感兴趣的端口。
我知道如何用 C 来做到这一点;查看 USBView 应用程序,我们将需要使用 SetupAPI 来枚举控制器 (SetupDiEnumDeviceInfo),然后是集线器,然后使用 IOCTL 查询集线器以获取每个端口上的内容。
我想我必须这样做,因为我无法从 COM13 找出映射 -> \.\USB#ROOT_HUB30#4&2a9d917a&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}..有没有更好/更简单的获取ioctl所需的文件名的方法,而不是全部通过并过滤它们?
我还尝试将 usbview 应用程序制作成 C DLL 并尝试围绕它制作一个包装器,但我无法让我自己开发的 DLL 正确编译...
我尝试将其从 usbview 添加到enum.c作为起点
typedef struct
{
PSTR Name;
PSTR path;
int port;
} USBDevice;
USBDevice USBDevices[255] = { 0 };
int ndevices;
extern __declspec(dllexport) int GetDevices(PSTR filter)
{
//Enumerate it all and filter for "COM%"
//Store the data in the USBDevice array.
}
extern __declspec(dllexport) PSTR DeviceName(int i)
{
return USBDevices[i].Name;
}
extern __declspec(dllexport) PSTR DevicePath(int i)
{
return USBDevices[i].path;
}
extern __declspec(dllexport) void FreeList(void)
{
char* foo;
int i;
for (i = 0; i<ndevices; i++)
{
free(USBDevices[i].Name);
free(USBDevices[i].path);
}
ndevices = 0;
}
extern __declspec(dllexport) PUSB_COMMON_DESCRIPTOR GetDevuceInfo(PSTR path, int port)
{
//I didn't want to figure out how to marshal this.
}
extern __declspec(dllexport) PSTR GetDevuceInfoValue(PSTR path,int port, int selector)
{
//Open Hub, send IOCTL to it, get data, filter that, return the interesting bit.
}
但是我无法将生成的 DLL 加载到我的 C# 项目中(它在运行时崩溃 - 甚至在窗口出现之前)。查看 DLL,它似乎是垃圾(遍历 DLL 会导致 walker 崩溃)。所以......我不确定我在那里做错了什么,所以我打算将 enum.c 翻译成 C# pinvoke 风格并继续使用它,但这似乎需要做很多工作,特别是如果有一个获取 COM14 的更简单方法 -> \.\USB#ROOT_HUB30#4&2a9d917a&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8} [Port1] 链接...
所以...我前面有很多工作要做,还是有更简单的方法来获取链接(我已经从注册表尝试过,但它似乎没有映射)。