UWP/C# - AQS 和 USB 设备的问题

Posted

技术标签:

【中文标题】UWP/C# - AQS 和 USB 设备的问题【英文标题】:UWP/C# - Issue with AQS and USB Devices 【发布时间】:2016-12-01 02:18:39 【问题描述】:

我尝试编写的 UWP 应用存在问题。我正在连接到我已编程的自定义嵌入式 USB 批量设备(它实际上是赛普拉斯半导体的开箱即用示例)。我正在使用 WinUSB.sys 驱动程序,使用设备中的嵌入式 MS OS 字符串来允许使用设备,而无需编写自定义 INF 文件来调用 WinUSB.sys 驱动程序。

在我的代码中,我使用 UsbDevice.GetDeviceSelector 方法返回一个 AQS,然后可以将其传递给 DeviceInformation.FindAllAsync 以开始与我的应用程序中的设备进行通信。我已经确认设备显示在设备管理器中没有任何问题,并且我已经检查了注册表以确保它具有接口 GUID。我有一个来自 USBViewer 的屏幕截图来显示设备的配置。这种查找和连接 USB 设备的方法来自这个 MSDN 示例,找到了 here。

当我使用 UsbDevice.GetDeviceSelector 方法时,它返回一个与此设备无关的 GUID。它返回的 GUID 实际上与 Lumia 电话 (DEE824EF-729B-4A0E-9C14-B7117D33A817) 相关联。因此,它找不到我的设备连接到系统。

为了排除故障,我都调用了 DeviceInformation.FindAllAsync,不带任何参数来查看我的设备是否在列表中,并且它确实找到了该设备(在已连接到我的机器的 1000 多个其他设备中)。然后,我在没有 GetDeviceSelector 方法的帮助下编写了一个自定义 AQS 字符串,仅从 GUID 开始。这样做会返回 27 个设备,但是当我尝试将 VID 和 PID 添加到此 AQS 字符串时,没有返回任何内容。

我还确保我要使用的设备按其相应的 VID 和 PID 在应用清单中列出,因为这是自定义类为 0xFF 的设备所必需的。我使用了自定义 USB UWP 设备示例,它可以找到该设备,尽管它使用完全不同的方法和设备选择器,如果需要,我会使用它,但这不是我的愿望,因为它是应用程序的一部分没有那么干净的解决方案。

我已经在 MSDN 论坛here 上发布了这个问题,并提供了更多信息,但我在那里没有得到很多参与。任何帮助,将不胜感激。我知道我一定遗漏了一些简单的东西。

亚当

private async void button_Click(object sender, RoutedEventArgs e) 

  //UInt32 vid = 0x04B4;
  //UInt32 pid = 0x00F0;

  UInt32 vid = uint.Parse(textBox1.Text, System.Globalization.NumberStyles.HexNumber);
  UInt32 pid = UInt32.Parse(textBox2.Text, System.Globalization.NumberStyles.HexNumber);
  Guid winusbInterfaceGuid = new Guid("a5dcbf10-6530-11d2-901f-00c04fb951ed");
  //string aqs = UsbDevice.GetDeviceSelector(vid, pid);
  string aqs = UsbDevice.GetDeviceSelector(winusbInterfaceGuid);



  var myDevices = await DeviceInformation.FindAllAsync(aqs, null);
  //var myDevices = await DeviceInformation.FindAllAsync();

  var myDevicesCount = myDevices.Count;

  if (myDevicesCount >= 1) 
  
    textBlock2.Text = "Device Found";
   else 
  
    textBlock2.Text = "Searching";
    await Task.Delay(1000);
    textBlock2.Text = "looking for device";
  

【问题讨论】:

抱歉,我不能添加超过 2 个链接。我有两张图片要上传,但作为新用户,我受到了限制。 请尝试最新的CustomUsbDeviceAccess 示例。它没有使用完全不同的方法,它只是使用 `var osrFx2Selector = UsbDevice.GetDeviceSelector(OsrFx2.DeviceVid, OsrFx2.DevicePid);` 来创建 aqs。然后调用CreateWatcher 方法。请将您的 aqs 与官方样本进行比较。 正如你所说的官方样品可以很好地工作,意味着已经有适合你的解决方案。请检查并比较你的不同之处。 @Sunteen-MSFT 我刚刚检查了最新版本,但它似乎不起作用。我需要去看看我是否有旧版应用程序的本地副本,看看它是否仍然有效。我什至尝试更改我的 VID/PID 以匹配与 Mutt 设备关联的 VID/PID 之一,但没有成功。 【参考方案1】:

刚刚给您发了一封询问进度的邮件(我想,不得不猜测您的邮件地址),但现在看来我自己找到了解决方案。请在UWP app cannot find/connect to USB device查看我的回答

简而言之,您必须创建一个 inf 来安装 winusb 驱动程序。我不知道为什么,但这对我有用(和其他人,请参阅Cannot create UsbDevice from DeviceInformation.Id)

【讨论】:

哇,抱歉,我以为我会收到一封邮件通知来回复此线程,但我没有。我会看看你发布的内容。我没有收到您发送的电子邮件。您可以在 Twitter 上的 Aeroengineer1 句柄下找到我。我可以从那里给你发私信。【参考方案2】:

Guid DEE824EF-729B-4A0E-9C14-B7117D33A817 实际上是标准的 WinUSB Guid。我认为这与 Lumia 手机无关。我不知道为什么它没有在任何地方记录。我认为您指定的 Guid a5dcbf10-6530-11d2-901f-00c04fb951ed 实际上是一条红鲱鱼。我也错误地使用了它,但它只是把我带到了花园小路上。它显示了 USB 接口,但我无法连接到它们。

您可能想试试这个课程 https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Usb.Net.UWP/UWPUsbDevice.cs 。

这是它获取设备的方式:

    public async Task<IEnumerable<DeviceDefinition>> GetConnectedDeviceDefinitions(uint? vendorId, uint? productId)
    
        var aqsFilter = "System.Devices.InterfaceClassGuid:=\"DEE824EF-729B-4A0E-9C14-B7117D33A817\" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND " + $" System.DeviceInterface.WinUsb.UsbVendorId:=vendorId.Value AND System.DeviceInterface.WinUsb.UsbProductId:=productId.Value";

        var deviceInformationCollection = await wde.DeviceInformation.FindAllAsync(aqsFilter).AsTask();

        //TODO: return the vid/pid if we can get it from the properties. Also read/write buffer size

        var deviceIds = deviceInformationCollection.Select(d => new DeviceDefinition  DeviceId = d.Id, DeviceType = DeviceType.Usb ).ToList();
        return deviceIds;
    

此示例连接到设备,我认为您将能够以相同的方式连接到设备:

        private static async Task InitializeTrezor()
        
            //Register the factory for creating Usb devices. This only needs to be done once.
            UWPUsbDeviceFactory.Register();

            //Register the factory for creating Usb devices. This only needs to be done once.
            UWPHidDeviceFactory.Register();

            //Note: other custom device types could be added here

            //Define the types of devices to search for. This particular device can be connected to via USB, or Hid
            var deviceDefinitions = new List<DeviceDefinition>
            
                new DeviceDefinition DeviceType= DeviceType.Hid, VendorId= 0x534C, ProductId=0x0001, Label="Trezor One Firmware 1.6.x" ,
                new DeviceDefinition DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C1, ReadBufferSize=64, WriteBufferSize=64, Label="Trezor One Firmware 1.7.x" ,
                new DeviceDefinition DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C0, ReadBufferSize=64, WriteBufferSize=64, Label="Model T" 
            ;

            //Get the first available device and connect to it
            var devices = await DeviceManager.Current.GetDevices(deviceDefinitions);
            var trezorDevice = devices.FirstOrDefault();
            await trezorDevice.InitializeAsync();

            //Create a buffer with 3 bytes (initialize)
            var buffer = new byte[64];
            buffer[0] = 0x3f;
            buffer[1] = 0x23;
            buffer[2] = 0x23;

            //Write the data to the device
            await trezorDevice.WriteAsync(buffer);

            //Read the response
            var readBuffer = await trezorDevice.ReadAsync();
      

如果您以这种方式连接到设备,您将通过 Device.Net (https://github.com/MelbourneDeveloper/Device.Net) 免费获得 Windows 经典版和 android 支持

【讨论】:

文档不多,但有这个 - docs.microsoft.com/en-us/uwp/api/windows.devices.usb.usbdevice。它只有一个示例“设备实例路径”,其中包括 DEE824EF-729B-4A0E-9C14-B7117D33A817 GUID。 也很有趣,当我在开发人员选项中启用 USB 调试时,我可以看到 DEE824EF-729B-4A0E-9C14-B7117D33A817;禁用 USB 调试时我看不到它。在这两种情况下,我都看到 A5DCBF10-6530-11D2-901F-00C04FB951ED。【参考方案3】:

使用 .NET 5 的 Device.net 的 DeviceManager.Current.GetDevices(deviceDefinitions) 我找不到任何连接到我的 win10 的设备,可以通过 ManagementObjectSearcher 轻松选择:

public List<ManagementBaseObject> GetLogicalDevices()

   List<ManagementBaseObject> devices = new List<ManagementBaseObject>();
   ManagementObjectCollection collection;
   ManagementObjectSearcher seacher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM CIM_LogicalDevice");
   collection = seacher.Get();

   foreach (var device in collection)
   
       devices.Add(device);
   

   return devices;

【讨论】:

以上是关于UWP/C# - AQS 和 USB 设备的问题的主要内容,如果未能解决你的问题,请参考以下文章

USB HID 设备检测

7 Linux usb驱动框架分析

在 Linux 中制作 USB 视频

AQS面试题

AQS共享锁和独占锁

linux usb 设备重新挂载