如何使用 C# 检测不存在的设备

本文关键字:不存在 检测 何使用 | 更新日期: 2023-09-27 18:34:35

我的程序(完全用 C# 编写(有一个用例,其中程序需要检测计算机中是否安装了特定的 USB 设备。在连接USB设备的情况下,WMI将解决此问题。

但是,如果设备未连接(不存在设备(,则WMI将无法提供帮助。我知道setupdi可能有助于解决此问题,但是我不完全熟悉C++并且由于符合代码的现有部分,添加编组功能的额外努力非常重要。

因此,我的问题是是否有等效的 c# 方法来检测系统中不存在的设备?我也尝试了注册表搜索方法,但是驱动程序是 HKLM''System''CurrentControlSet''services''WinUSB 下的通用 USB 驱动程序,并且没有其他信息可用于识别 USB 驱动程序对应于我们感兴趣的特定设备。

另一个可能的标识信息是设备管理器中"驱动程序"选项卡中的"驱动程序提供程序"信息。USB 设备具有可用于标识设备的非常具体的驱动程序提供程序信息。但是,我不知道现有的API来检索此信息。

非常感谢您的帮助,并期待任何可能的解决方案

如何使用 C# 检测不存在的设备

不知道这是否有帮助。这是我大约 7 年前写的几段代码,从那以后就没有使用过 - 该项目被放弃了。不幸的是,整个 USB 接口大约有 700 行 C# - 太多了,无法在这里发布。

   /// <summary>
   /// This class represents a USB HID (Human Interface Device) device.
   /// </summary>
   public class UsbHidDevice : IDisposable
   {
      // The Windows GUID for HID USB devices
      private Guid _deviceClass;
      // The full "path name" of the device (set when found)
      private string _devicePath;

      #region Constructor
      public UsbHidDevice()
      {
         // Initialize the Windows GUID for HID devices
         Win32API.HidD_GetHidGuid(out _deviceClass);
      }
      #endregion Constructor

      /// <summary>
      /// Function to search the USB devices to see if the desired one is online.
      /// </summary>
      /// <param name="vendorId">vendor ID, or zero if not significant</param>
      /// <param name="productId">product ID</param>
      public bool FindDevice(int vendorId, int productId)
      {
         string strSearch;
         // Build the path search string
         if (vendorId == 0)
            strSearch = string.Format("pid_{0:x4}", productId);
         else
            strSearch = string.Format("vid_{0:x4}&pid_{1:x4}", vendorId, productId);
         // Prepare to search the USB device table in Windows
         // This gets a list of all HID devices currently connected to the computer (InfoSet)
         IntPtr hInfoSet = Win32API.SetupDiGetClassDevs(ref _deviceClass, null, IntPtr.Zero, Win32API.DIGCF_DEVICEINTERFACE | Win32API.DIGCF_PRESENT);
         try
         {
            // Build up a device interface data block
            Win32API.DeviceInterfaceData oInterface = new Win32API.DeviceInterfaceData();
            oInterface.Size = Marshal.SizeOf(oInterface);
            // Now iterate through the InfoSet memory block assigned within Windows in the 
            //  call to SetupDiGetClassDevs to get device details for each device connected
            int nIndex = 0;
            // This gets the device interface information for a device at index 'nIndex' in the memory block
            while (Win32API.SetupDiEnumDeviceInterfaces(hInfoSet, 0, ref _deviceClass, (uint)nIndex, ref oInterface))
            {
               // Get the device path (see helper method 'GetDevicePath')
               string strDevicePath = GetDevicePath(hInfoSet, ref oInterface);
               // Do a string search, if we find the VID/PID string then we found our device
               if (!string.IsNullOrEmpty(strDevicePath) && strDevicePath.IndexOf(strSearch) >= 0)
               {
                  _devicePath = strDevicePath;
                  return true;
               }
               // If we get here, we didn't find our device. So move on to the next one.
               log.Debug("FindDevice() - Incorrect device found, keep searching." + strDevicePath);
               nIndex++;
            }
         }
         catch (Exception e)
         {
            log.Error("FindDevice() - Exception:", e);
         }
         finally
         {
            // Before we go, we have to free up the InfoSet memory reserved by SetupDiGetClassDevs
            Win32API.SetupDiDestroyDeviceInfoList(hInfoSet);
         }
         // Device not found
         return false;
      }
... other methods not included here
   }

   /// <summary>
   /// Definition of some Windows API stuff.
   /// 
   /// This is copied from "A USB HID Component for C#" (also called "Sniffer"), By "wimar"
   ///  http://www.codeproject.com/KB/cs/USB_HID.aspx
   /// </summary>
   internal class Win32API
   {
      // Used in SetupDiClassDevs to get devices present in the system
      public const int DIGCF_PRESENT = 0x02;
      // Used in SetupDiClassDevs to get device interface details
      public const int DIGCF_DEVICEINTERFACE = 0x10;

      /// <summary>
      /// Provides details about a single USB device
      /// 
      /// The field "Reserved" has been changed from int to UIntPtr based on information on web page
      /// http://www.codeproject.com/KB/cs/USB_HID.aspx, see message "Does not work on 64 bit Vista?".
      /// </summary>
      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      public struct DeviceInterfaceData
      {
         public int Size;
         public Guid InterfaceClassGuid;
         public int Flags;
         public UIntPtr Reserved;
      }

      /// <summary>
      /// Gets the GUID that Windows uses to represent HID class devices
      /// </summary>
      /// <param name="gHid">An out parameter to take the Guid</param>
      [DllImport("hid.dll", SetLastError = true)]
      public static extern void HidD_GetHidGuid(out Guid gHid);
      /// <summary>
      /// Allocates an InfoSet memory block within Windows that contains details of devices.
      /// </summary>
      /// <param name="gClass">Class guid (e.g. HID guid)</param>
      /// <param name="strEnumerator">Not used</param>
      /// <param name="hParent">Not used</param>
      /// <param name="nFlags">Type of device details required (DIGCF_ constants)</param>
      /// <returns>A reference to the InfoSet</returns>
      [DllImport("setupapi.dll", SetLastError = true)]
      public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, [MarshalAs(UnmanagedType.LPStr)] string strEnumerator, IntPtr hParent, uint nFlags);

      /// <summary>
      /// Gets the DeviceInterfaceData for a device from an InfoSet.
      /// </summary>
      /// <param name="lpDeviceInfoSet">InfoSet to access</param>
      /// <param name="nDeviceInfoData">Not used</param>
      /// <param name="gClass">Device class guid</param>
      /// <param name="nIndex">Index into InfoSet for device</param>
      /// <param name="oInterfaceData">DeviceInterfaceData to fill with data</param>
      /// <returns>True if successful, false if not (e.g. when index is passed end of InfoSet)</returns>
      [DllImport("setupapi.dll", SetLastError = true)]
      public static extern bool SetupDiEnumDeviceInterfaces(IntPtr lpDeviceInfoSet, uint nDeviceInfoData, ref Guid gClass, uint nIndex, ref DeviceInterfaceData oInterfaceData);

      /// <summary>
      /// Frees InfoSet allocated in call to above.
      /// </summary>
      /// <param name="lpInfoSet">Reference to InfoSet</param>
      /// <returns>true if successful</returns>
      [DllImport("setupapi.dll", SetLastError = true)]
      public static extern int SetupDiDestroyDeviceInfoList(IntPtr lpInfoSet);
... other stuff missing
   }

如代码中的注释中所述,这是基于以下内容:http://www.codeproject.com/Articles/18099/A-USB-HID-Component-for-C

我可能省略了一些需要的东西 - 让我知道。

        string ComputerName = "localhost";
        ManagementScope Scope;
        Scope = new ManagementScope(String.Format("''''{0}''root''CIMV2", ComputerName), null);
        Scope.Connect();
        string query = "SELECT * FROM Win32_PnPEntity Where ClassGuid = NULL";
        ObjectQuery Query = new ObjectQuery(query);
        ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
        foreach (ManagementObject WmiObject in Searcher.Get())
        {
            textBox1.Text += WmiObject["Name"] + "'r'n";
        }