我正在尝试动态列出与某个UsbDeviceClass匹配的连接到计算机的USB
关于我尝试在设备管理器中列出的USB类别的信息如下所示

理想情况下,它应该能够列出Com端口,因为我要列出的设备特别是Arduinos。
DeviceInformationCollection usbDeviceInfoCollection = await DeviceInformation.FindAllAsync(UsbDevice.GetDeviceClassSelector(new UsbDeviceClass()
{
ClassCode = 0x02,
SubclassCode = 0x02,
ProtocolCode = 0x01
}));
Debug.WriteLineIf(usbDeviceInfoCollection.Count == 1, "1 USB device found");
Debug.WriteLineIf(usbDeviceInfoCollection.Count != 1, usbDeviceInfoCollection.Count + " USB devices found");
for (int i = 0; i < usbDeviceInfoCollection.Count; i++)
{
Debug.WriteLine("USB Device " + (i + 1));
Debug.WriteLine("ID: " + usbDeviceInfoCollection[i].Id);
Debug.WriteLine("Name: " + usbDeviceInfoCollection[i].Name);
Debug.WriteLine("Properties: " + usbDeviceInfoCollection[i].Properties);
Debug.WriteLine("");
}上面的代码显示了我是如何尝试实现这一点的,但到目前为止,我还没有成功。这是因为当程序运行时,当连接了一个设备时,它返回0个设备。
我也尝试过使用预定义的类UsbDeviceClasses.CdcControl,但是也没有达到我想要的结果。
我非常感谢任何关于如何正确实现这一点的指导。
另外,由于这是一个UWP项目,我已经包含了下面的功能,所以它应该能够检测到我想要的设备。
<DeviceCapability Name="serialcommunication">
<Device Id="any">
<Function Type="name:serialPort"/>
</Device>
</DeviceCapability>根据jsanalytics的建议,使用不带UsbDeviceClass的DeviceInformation.FindAllAsync()对程序进行了轻微更改,输出了Arduino信息的示例。
Device 1354
EnclosureLocation: Windows.Devices.Enumeration.EnclosureLocation
ID: \\?\USB#VID_2341&PID_0243#9543231323835131B172#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
IsDefault: False
IsEnabled: True
Kind: DeviceInterface
Name: Genuino Uno (COM6)
Pairing: Windows.Devices.Enumeration.DeviceInformationPairing
Properties: System.__ComObject注册表图像

更新,有关于包括name:cdcControl, classId:02 * *的更具体的USB功能的this page。但是,我仍然不能让它像这个远程arduino应用程序那样通过连接的设备进行枚举;Windows Remote Arduino Experience。
用于澄清的快速编辑。我不是无法连接到该设备,我只是无法枚举属于02类02子类02协议01的设备。可以通过指定VID和PID连接到我的设备,但在当前情况下,这违背了要点。
发布于 2018-01-01 23:53:36
您可以枚举外部USB设备,首先需要在Package.appxmanifest文件中添加此权限。
<uap:Capability Name="removableStorage" />然后在你的应用程序中编写这段代码。
var removableDevices = KnownFolders.RemovableDevices;
var externalDrives = await removableDevices.GetFoldersAsync();
foreach (var item in externalDrives)
{
var name = item.DisplayName;
}现在为了有一个刷新列表,重新运行代码。
发布于 2020-12-23 08:54:27
SerialDevice.GetDeviceSelector()可以用来回答我枚举串行设备的特定场景。
DeviceInformationCollection deviceSearchResults = await DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelector());但是,看看如何使用类、子类和协议来列出相同的信息的问题,就不清楚了。
UsbDevice.GetDeviceClassSelector(new UsbDeviceClass
{
ClassCode = 0x02,
SubclassCode = 0x02,
ProtocolCode = 0x01
});上面的代码生成字符串
System.Devices.InterfaceClassGuid:="{DEE824EF-729B-4A0E-9C14-B7117D33A817}" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND System.DeviceInterface.WinUsb.UsbClass:=2 AND System.DeviceInterface.WinUsb.UsbSubClass:=2 AND System.DeviceInterface.WinUsb.UsbProtocol:=1这不起作用有两个原因。
第一个可以在查看System.Devices.InterfaceClassGuid时看到。列出的串行端口的此属性的值不是DEE824EF-729B-4A0E-9C14-B7117D33A817,而是86e0d1e0-8089-11d0-9ce4-08003e301f73。SerialDevice.GetDeviceSelector()似乎在返回时考虑到了这一点
System.Devices.InterfaceClassGuid:="{86E0D1E0-8089-11D0-9CE4-08003E301F73}" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True第二种情况是,当使用DeviceInformation.FindAllAsync加载额外的参数时,这些参数实际上是空的,您希望这些参数与问题屏幕截图中显示的值匹配。
代码
private async void List()
{
DeviceInformationCollection deviceSearchResults = await DeviceInformation.FindAllAsync("", new[]
{
"System.Devices.InterfaceClassGuid",
"System.DeviceInterface.Serial.PortName",
"System.DeviceInterface.Serial.UsbProductId",
"System.DeviceInterface.Serial.UsbVendorId",
"System.Devices.CompatibleIds",
"System.Devices.ClassGuid",
"System.DeviceInterface.WinUsb.UsbClass",
"System.DeviceInterface.WinUsb.UsbSubClass",
"System.DeviceInterface.WinUsb.UsbProtocol",
});
foreach (DeviceInformation device in deviceSearchResults)
{
PrintInfo(device);
}
}
private static void PrintInfo(DeviceInformation device)
{
Debug.WriteLine("Device:");
Debug.WriteLine($"\tID: {device.Id}");
Debug.WriteLine($"\tName: {device.Name}");
Debug.WriteLine($"\tIs Enabled: {device.IsEnabled}");
Debug.WriteLine($"\tIs Default: {device.IsDefault}");
Debug.WriteLine($"\tKind: {device.Kind}");
if (device.EnclosureLocation != null)
{
Debug.WriteLine("\tEnclosure Location:");
Debug.WriteLine($"\t\tIn Dock: {device.EnclosureLocation.InDock}");
Debug.WriteLine($"\t\tIn Lid: {device.EnclosureLocation.InLid}");
Debug.WriteLine($"\t\tPanel: {device.EnclosureLocation.Panel}");
Debug.WriteLine($"\t\tRotation Angle In Degrees Clockwise: {device.EnclosureLocation.RotationAngleInDegreesClockwise}");
}
if (device.Pairing != null)
{
Debug.WriteLine("\tPairing Info:");
Debug.WriteLine($"\t\tCan Pair: {device.Pairing.CanPair}");
Debug.WriteLine($"\t\tIs Paired: {device.Pairing.IsPaired}");
Debug.WriteLine($"\t\tProtection Level: {device.Pairing.ProtectionLevel}");
}
Debug.WriteLine("\tProperties:");
foreach ((string key, object value) in device.Properties)
{
Debug.WriteLine($"\t\t{key}: {value}");
}
Debug.WriteLine("");
}返回以下输出,显示其他参数(如CompatibleIds )为空。
Device:
ID: \\?\USB#VID_2341&PID_0043#9563533333135161B150#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
Name: USB Serial Device (COM3)
Is Enabled: True
Is Default: False
Kind: DeviceInterface
Enclosure Location:
In Dock: False
In Lid: False
Panel: Right
Rotation Angle In Degrees Clockwise: 0
Pairing Info:
Can Pair: False
Is Paired: False
Protection Level: None
Properties:
System.ItemNameDisplay: USB Serial Device (COM3)
System.Devices.DeviceInstanceId: USB\VID_2341&PID_0043\9563533333135161B150
System.Devices.Icon: C:\Windows\System32\DDORes.dll,-2001
System.Devices.GlyphIcon: C:\Windows\System32\DDORes.dll,-3001
System.Devices.InterfaceEnabled: True
System.Devices.IsDefault: False
System.Devices.PhysicalDeviceLocation: System.Byte[]
System.Devices.ContainerId: 57921dd6-46ab-5d6d-a362-0a14d0827375
System.Devices.InterfaceClassGuid: 86e0d1e0-8089-11d0-9ce4-08003e301f73
System.DeviceInterface.Serial.PortName: COM3
System.DeviceInterface.Serial.UsbProductId: 67
System.DeviceInterface.Serial.UsbVendorId: 9025
System.Devices.CompatibleIds:
System.Devices.ClassGuid:
System.DeviceInterface.WinUsb.UsbClass:
System.DeviceInterface.WinUsb.UsbSubClass:
System.DeviceInterface.WinUsb.UsbProtocol: 顺便说一句,如果有人希望在WPF /其他桌面应用程序中实现类似的功能,这是我当时采用的方法,可以通过几种方式使用WMI来实现。
// If in .NET Core / .NET 5 run
// Install-Package System.Management -Version 5.0.0
// See https://www.nuget.org/packages/System.Management/
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("SELECT * FROM Win32_SerialPort");
foreach (ManagementBaseObject queryObj in searcher.Get())
{
Debug.WriteLine("COM Port");
Debug.WriteLine($"DeviceID: {queryObj["DeviceID"]}");
Debug.WriteLine($"Name: {queryObj["NAME"]}");
Debug.WriteLine($"Description: {queryObj["Description"]}");
Debug.WriteLine($"PNPDeviceID: {queryObj["PNPDeviceID"]}");
Debug.WriteLine("");
}
// If in .NET Core / .NET 5 run
// Install-Package Microsoft.Management.Infrastructure -Version 2.0.0
// See https://www.nuget.org/packages/Microsoft.Management.Infrastructure/
CimSession cimSession = CimSession.Create(null);
IEnumerable<CimInstance> queryInstances =
cimSession.QueryInstances(@"root\cimv2",
"WQL",
@"SELECT * FROM Win32_SerialPort");
foreach (CimInstance cimInstance in queryInstances)
{
Debug.WriteLine("COM Port");
Debug.WriteLine($"DeviceID: {cimInstance.CimInstanceProperties["DeviceID"].Value}");
Debug.WriteLine($"Name: {cimInstance.CimInstanceProperties["NAME"].Value}");
Debug.WriteLine($"Description: {cimInstance.CimInstanceProperties["Description"].Value}");
Debug.WriteLine($"PNPDeviceID: {cimInstance.CimInstanceProperties["PNPDeviceID"].Value}");
Debug.WriteLine("");
}UWP的WMI / CIM方法的问题是,即使可以安装NuGets,也不支持它。一种解决方案是使用桌面桥将Win32代码包含在UWP应用程序中作为后台进程。有关详细信息,请参阅here和here。
一个似乎能够获得大量关于USB的信息的资源是USB View。它不是用C#编写的,但它是开源的,而且是用C编写的,所以它可能可以翻译成C#。
https://stackoverflow.com/questions/48023626
复制相似问题