【问题标题】:Getting the Drive letter of USB drive inserted获取插入的 USB 驱动器的驱动器号
【发布时间】:2014-11-12 19:00:49
【问题描述】:

按照给定链接How do I detect when a removable disk is inserted using C#?中的建议,我检测到在我的 WPF 应用程序中插入了 USB 驱动器

但我无法确定检测到的 USB 驱动器的驱动器号;我的代码如下所示

    static ManagementEventWatcher w = null;
    static void AddInsertUSBHandler()
    {

        WqlEventQuery q;
        ManagementScope scope = new ManagementScope("root\\CIMV2");
        scope.Options.EnablePrivileges = true;

        try {

            q = new WqlEventQuery();
            q.EventClassName = "__InstanceCreationEvent";
            q.WithinInterval = new TimeSpan(0, 0, 3);
            q.Condition = "TargetInstance ISA 'Win32_USBControllerdevice'";
            w = new ManagementEventWatcher(scope, q);
            w.EventArrived += USBInserted;

            w.Start();
        }
        catch (Exception e) {

            Console.WriteLine(e.Message);
            if (w != null)
            {
                w.Stop();

            }
        }

    }

    static void USBInserted(object sender, EventArgs e)
    {

        Console.WriteLine("A USB device inserted");

    } 

如果可能,请指导我。

【问题讨论】:

    标签: c#


    【解决方案1】:

    希望这会有所帮助,其代码基于 Neeraj Dubbey 的回答。

    我们在一个连续的多线程循环中运行代码,不断检查连接的 USB 设备的变化。因为我们跟踪以前连接的设备,所以我们可以将其与新的设备列表进行比较。我们还可以使用相同的方法确定设备是否被移除。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Management;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace Usb_Test
    {
        class Program
        {
            private static List<USBDeviceInfo> previousDecices = new List<USBDeviceInfo>();
    
            static void Main(string[] args)
            {
                Thread thread = new Thread(DeviceDetection);
                thread.Start();
    
                Console.Read();
            }
    
            static void DeviceDetection()
            {
                while (true)
                {
                    List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
    
                    ManagementObjectCollection collection;
                    using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
                        collection = searcher.Get();
    
                    foreach (var device in collection)
                    {
                        devices.Add(new USBDeviceInfo(
                        (string)device.GetPropertyValue("DeviceID")
                        ));
                    }
    
                    if (previousDecices == null || !previousDecices.Any()) // So we don't detect already plugged in devices the first time.
                        previousDecices = devices;
    
                    var insertionDevices = devices.Where(d => !previousDecices.Any(d2 => d2.DeviceID == d.DeviceID));
                    if (insertionDevices != null && insertionDevices.Any())
                    {
                        foreach(var value in insertionDevices)
                        {
                            Console.WriteLine("Inserted: " + value.DeviceID); // Add your own event for the insertion of devices.
                        }
                    }    
    
                    var removedDevices = previousDecices.Where(d => !devices.Any(d2 => d2.DeviceID == d.DeviceID));
                    if (removedDevices != null && removedDevices.Any())
                    {
                        foreach (var value in removedDevices)
                        {
                            Console.WriteLine("Removed: " + value.DeviceID); // Add your own event for the removal of devices.
                        }
                    }
    
                    previousDecices = devices;
                    collection.Dispose();
                }
            }
        }
    
        class USBDeviceInfo
        {
            public USBDeviceInfo(string deviceID)
            {
                this.DeviceID = deviceID;
            }
            public string DeviceID { get; private set; }
    
        }
    }
    

    但这不是一个很好的解决方案,你最好听听 WM_DEVICECHANGE。

    Windows 将在任何时候向所有应用程序发送 WM_DEVICECHANGE 消息 发生某些硬件更改,包括当闪存驱动器(或其他 可移动设备)被插入或移除。这个的 WParam 参数 message 包含的代码准确地指定了发生了什么事件。为了 我们的目的只有以下事件是有趣的:

    DBT_DEVICEARRIVAL - 在设备或媒体被发送后发送 插入。当设备启动时,您的程序将收到此消息 准备使用,大约在资源管理器显示对话框的时候 这使您可以选择如何处理插入的媒体。

    DBT_DEVICEQUERYREMOVE - 当系统请求权限时发送 移除设备或媒体。任何应用程序都可以否认这一点 请求并取消删除。这是重要的事件,如果你 需要在闪存驱动器上执行一些操作才能将其移除, 例如加密一些文件就可以了。您的程序可以拒绝此请求 这将导致 Windows 显示众所周知的消息,说明 现在无法移除该设备。

    DBT_DEVICEREMOVECOMPLETE - 在设备被移除后发送。什么时候 您的程序收到此事件,设备不再可用 - 在 Windows 显示其“设备已被移除”气泡时 给用户。

    这里有一些链接,每个链接都详细说明了如何在 C# 中执行此操作:

    http://www.codeproject.com/Articles/18062/Detecting-USB-Drive-Removal-in-a-C-Program http://www.codeproject.com/Articles/60579/A-USB-Library-to-Detect-USB-Devices

    这两种解决方案都应该有效,您可以随时调整它们以满足您的需求。

    【讨论】:

      【解决方案2】:

      嘿,试试这个基于控制台的代码,在项目中添加System.Management 的引用

      namespace ConsoleApplication1
      {
       using System;
       using System.Collections.Generic;
       using System.Management; // need to add System.Management to your project references.
      
      class Program
      {
      static void Main(string[] args)
      {
          var usbDevices = GetUSBDevices();
      
          foreach (var usbDevice in usbDevices)
          {
              Console.WriteLine("Device ID: {0}", usbDevice.DeviceID);
      
          }
      
          Console.Read();
      }
      
      static List<USBDeviceInfo> GetUSBDevices()
      {
          List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
      
          ManagementObjectCollection collection;
          using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
              collection = searcher.Get();
      
          foreach (var device in collection)
          {
              devices.Add(new USBDeviceInfo(
              (string)device.GetPropertyValue("DeviceID")
              ));
          }
      
          collection.Dispose();
          return devices;
      }
      }
      
      class USBDeviceInfo
      {
      public USBDeviceInfo(string deviceID)
      {
          this.DeviceID = deviceID;
      }
      public string DeviceID { get; private set; }
      
      }
      

      【讨论】:

      • 问题是此代码仅适用于已插入的设备,我想在插入 USB 驱动器时选择驱动器号
      猜你喜欢
      • 2012-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2019-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多