首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过USB类别列出USB设备

通过USB类别列出USB设备
EN

Stack Overflow用户
提问于 2017-12-29 21:49:57
回答 2查看 1.4K关注 0票数 19

我正在尝试动态列出与某个UsbDeviceClass匹配的连接到计算机的USB

关于我尝试在设备管理器中列出的USB类别的信息如下所示

理想情况下,它应该能够列出Com端口,因为我要列出的设备特别是Arduinos。

代码语言:javascript
复制
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项目,我已经包含了下面的功能,所以它应该能够检测到我想要的设备。

代码语言:javascript
复制
<DeviceCapability Name="serialcommunication">
  <Device Id="any">
    <Function Type="name:serialPort"/>
  </Device>
</DeviceCapability>

根据jsanalytics的建议,使用不带UsbDeviceClassDeviceInformation.FindAllAsync()对程序进行了轻微更改,输出了Arduino信息的示例。

代码语言:javascript
复制
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连接到我的设备,但在当前情况下,这违背了要点。

EN

回答 2

Stack Overflow用户

发布于 2018-01-01 23:53:36

您可以枚举外部USB设备,首先需要在Package.appxmanifest文件中添加此权限。

代码语言:javascript
复制
 <uap:Capability Name="removableStorage" />

然后在你的应用程序中编写这段代码。

代码语言:javascript
复制
    var removableDevices = KnownFolders.RemovableDevices;
    var externalDrives = await removableDevices.GetFoldersAsync();
    foreach (var item in externalDrives)
      {
          var name = item.DisplayName;
      }

现在为了有一个刷新列表,重新运行代码。

票数 1
EN

Stack Overflow用户

发布于 2020-12-23 08:54:27

SerialDevice.GetDeviceSelector()可以用来回答我枚举串行设备的特定场景。

代码语言:javascript
复制
DeviceInformationCollection deviceSearchResults = await DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelector());

但是,看看如何使用类、子类和协议来列出相同的信息的问题,就不清楚了。

代码语言:javascript
复制
UsbDevice.GetDeviceClassSelector(new UsbDeviceClass
{
    ClassCode = 0x02,
    SubclassCode = 0x02,
    ProtocolCode = 0x01
});

上面的代码生成字符串

代码语言:javascript
复制
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-08003e301f73SerialDevice.GetDeviceSelector()似乎在返回时考虑到了这一点

代码语言:javascript
复制
System.Devices.InterfaceClassGuid:="{86E0D1E0-8089-11D0-9CE4-08003E301F73}" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True

第二种情况是,当使用DeviceInformation.FindAllAsync加载额外的参数时,这些参数实际上是空的,您希望这些参数与问题屏幕截图中显示的值匹配。

代码

代码语言:javascript
复制
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 )为空。

代码语言:javascript
复制
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来实现。

代码语言:javascript
复制
// 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应用程序中作为后台进程。有关详细信息,请参阅herehere

一个似乎能够获得大量关于USB的信息的资源是USB View。它不是用C#编写的,但它是开源的,而且是用C编写的,所以它可能可以翻译成C#。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48023626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档