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

时间:2016-12-01 02:18:39

标签: c# usb uwp

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

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

当我使用UsbDevice.GetDeviceSelector方法时,它返回一个与此设备无关的GUID。它返回的GUID实际上与Lumia Phones(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";
  }
}

3 个答案:

答案 0 :(得分:0)

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

上查看我的回答

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

答案 1 :(得分:0)

GUID DEE824EF-729B-4A0E-9C14-B7117D33A817实际上是标准的WinUSB Guid。我认为这与Lumia Phones没有任何关系。我不知道为什么在任何地方都没有记录。我认为您指定的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支持

答案 2 :(得分:0)

使用 .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;
}