Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用WMI获取USB设备的驱动器号_C#_Wmi - Fatal编程技术网

C# 如何使用WMI获取USB设备的驱动器号

C# 如何使用WMI获取USB设备的驱动器号,c#,wmi,C#,Wmi,我需要跟踪C应用程序中的USB插入和删除事件,因此我根据其他问题提出了以下想法 我不能用这种方法 var drives = DriveInfo.GetDrives() .Where(drive => drive.IsReady && drive.DriveType == DriveType.Removable).ToList(); 因为当您需要区分已连接和已断开连接的设备时,这可能会导致很多问题,因此新设备可以与以前缓存的设备具有相同的驱动器号和名称 所以我决定使

我需要跟踪C应用程序中的USB插入和删除事件,因此我根据其他问题提出了以下想法

我不能用这种方法

var drives = DriveInfo.GetDrives()
    .Where(drive => drive.IsReady && drive.DriveType == DriveType.Removable).ToList();
因为当您需要区分已连接和已断开连接的设备时,这可能会导致很多问题,因此新设备可以与以前缓存的设备具有相同的驱动器号和名称

所以我决定使用WMI来解决这个问题,但我发现不可能通过Win32_USBHub类获取指定USB设备的驱动器号。然后我想我可以执行另一个这样的查询

foreach (ManagementObject device in new ManagementObjectSearcher(@"SELECT * FROM Win32_USBHub").Get())
{
    string deviceID = (string)device.GetPropertyValue("DeviceID");

    Console.WriteLine("{0}", deviceID);

    string query = string.Format("SELECT * FROM Win32_LogicalDisk WHERE DeviceID='{0}'", deviceID);
    foreach (ManagementObject o in new ManagementObjectSearcher(query).Get())
    {
        string name = (string)o.GetPropertyValue("Name");
        Console.WriteLine("{0}", name);
    }

    Console.WriteLine("==================================");
}
但它根本不起作用-每次尝试执行与Win32_LogicalDisk表一起工作的查询时,我都会收到一个异常无效查询

为什么??我做错了什么?我怎样才能修好它?也许有更好的方法来解决这个问题


提前感谢。

您会遇到一个异常,因为您的deviceID包含需要反斜杠转义的字符。使用simple replace,不应出现异常

string query = string.Format("SELECT * FROM Win32_LogicalDisk WHERE DeviceID='{0}'", deviceID.Replace(@"\", @"\\"));
然而,从WMI获取USB驱动器号要复杂一些。您需要学习一些课程,正如@MSalters在其评论中发布的链接所述:

Win32_DiskDrive-> Win32_DiskDriveToDiskPartition -> Win32_DiskPartition -> Win32_LogicalDiskToPartition -> Win32_LogicalDisk.
找到的代码的一个稍加修改的版本适合我:

foreach (ManagementObject device in new ManagementObjectSearcher(@"SELECT * FROM Win32_DiskDrive WHERE InterfaceType LIKE 'USB%'").Get())
{
    Console.WriteLine((string)device.GetPropertyValue("DeviceID"));
    Console.WriteLine((string)device.GetPropertyValue("PNPDeviceID"));                

    foreach (ManagementObject partition in new ManagementObjectSearcher(
        "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + device.Properties["DeviceID"].Value
        + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())
    {
        foreach (ManagementObject disk in new ManagementObjectSearcher(
                    "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='"
                        + partition["DeviceID"]
                        + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
        {
            Console.WriteLine("Drive letter " + disk["Name"]);
        }
    }
}

这是michalk针对C 8的答案的重构版本

我把它和这个相关问题的答案结合起来使用

        static IEnumerable<(string deviceId, string pnpDeviceId, string driveLetter)> SelectDeviceInformation()
        {
            foreach (ManagementObject device in SelectDevices())
            {
                var deviceId = (string)device.GetPropertyValue("DeviceID");
                var pnpDeviceId = (string)device.GetPropertyValue("PNPDeviceID");
                var driveLetter = (string)SelectPartitions(device).SelectMany(SelectDisks).Select(disk => disk["Name"]).Single();

                yield return (deviceId, pnpDeviceId, driveLetter);
            }

            static IEnumerable<ManagementObject> SelectDevices() => new ManagementObjectSearcher(
                    @"SELECT * FROM Win32_DiskDrive WHERE InterfaceType LIKE 'USB%'").Get()
                .Cast<ManagementObject>();

            static IEnumerable<ManagementObject> SelectPartitions(ManagementObject device) => new ManagementObjectSearcher(
                    "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=" +
                    "'" + device.Properties["DeviceID"].Value + "'} " +
                    "WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get()
                .Cast<ManagementObject>();

            static IEnumerable<ManagementObject> SelectDisks(ManagementObject partition) => new ManagementObjectSearcher(
                    "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=" +
                    "'" + partition["DeviceID"] + "'" +
                    "} WHERE AssocClass = Win32_LogicalDiskToPartition").Get()
                .Cast<ManagementObject>();
        }

回答你的问题了吗?@MSalters string query=string.FormatASSOCIATORS OF{{Win32_USBHub.DeviceID='{0}}}其中AssocClass=Win32_LogicalDisk,DeviceID;新ManagementObjectSearcherquery.Get{string name=stringo.GetPropertyValueName;Console.WriteLine{0},name;}中的foreach var o向我提供了无效的对象路径,例外情况为答案。顺便说一句,使用PNPDeviceID而不是DeviceID有什么意义?这是解决原始问题的最佳方法吗?我只是打印了PNPDeviceID以获得更清晰的输出,它不用于搜索过程。据我所知,PNPDeviceID是即插即用管理器使用的一些标准格式,DeviceID格式因类而异。这是最好的方法吗?我不知道。但考虑到提取这些信息所需的类的数量,它肯定是最短的。