之前已经提出过这个问题,并且有一个答案应该有效here。但我已经尝试过了,它对我不起作用。
问题是Win32_DiskDrive上的Query返回的PNPDeviceID和“Device”类返回的PNPDeviceID是不同的。例如,在我的情况下,查询返回类似于 - PNPDeviceID: USBSTOR \ DISK& VEN_ABCD& PROD_1234& REV_0001 \ 8& 2C3C9390& 0 的东西,而Device类返回实际的VID / PID组合 - >的 USB \ VID_4568&安培; PID_QWER&安培; MI_00 \ 7和; 15b8d7f0和3&安培; 0000
因此Win32_DiskDrive上的SELECT查询总是失败。
主要代码:
var usbDevices = GetUSBDevices();
//Enumerate the USB devices to see if any have specific VID/PID
foreach (var usbDevice in usbDevices)
{
if (usbDevice.DeviceID.Contains("ABCD") && usbDevice.DeviceID.Contains("1234"))
{
foreach (string name in usbDevice.GetDiskNames())
{
//Open dialog to show file names
Debug.WriteLine(name);
}
}
}
USBDeviceInfo类
class USBDeviceInfo
{
public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
{
this.DeviceID = deviceID;
this.PnpDeviceID = pnpDeviceID;
this.Description = description;
}
public string DeviceID { get; private set; }
public string PnpDeviceID { get; private set; }
public string Description { get; private set; }
public IEnumerable<string> GetDiskNames()
{
using (Device device = Device.Get(PnpDeviceID))
{
// get children devices
foreach (string childDeviceId in device.ChildrenPnpDeviceIds)
{
// get the drive object that correspond to this id (escape the id)
Debug.WriteLine(childDeviceId.Replace(@"\", @"\\") );
foreach (ManagementObject drive in new ManagementObjectSearcher("SELECT DeviceID FROM Win32_DiskDrive WHERE PNPDeviceID='" + childDeviceId.Replace(@"\", @"\\") + "'").Get())
{
foreach (PropertyData usb in drive.Properties){
if (usb.Value != null && usb.Value.ToString() != "")
{
Debug.Write(usb.Name + "=");
Debug.Write(usb.Value + "\r\n");
}
}
// associate physical disks with partitions
foreach (ManagementObject partition in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + drive["DeviceID"] + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition").Get())
{
// associate partitions with logical disks (drive letter volumes)
foreach (ManagementObject disk in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass=Win32_LogicalDiskToPartition").Get())
{
yield return (string)disk["DeviceID"];
}
}
}
}
}
}
作为旁注,我可以使用“Model”属性传递获取Query,然后找到驱动器号,如here所述。但我正在寻找一种可以将VID / PID与驱动器号联系起来的解决方案。
答案 0 :(得分:4)
我有完全相同的问题,经过一周的努力工作后,我终于得到了解决方案。 我还为一个设备获得了两个链接(带有vid和pid的链接以及一个包含“USBSTOR ....”的链接)。我认为这不是解决问题的最佳方法,但(直到现在)它才有效。
我使用了两个功能:
第一个是找到具有特定VID和PID的USBHub,还可以找到相关的第二个链接(“USBSTOR ....”)。此链接很重要,因为它形成了与驱动器号的连接。 名为“USBobjects”的列表包含许多相关链接(USBHub,USBSTOR,....),它们指的是所有连接的设备。我发现USBSTOR链接出现在链接之后,其中包含VID和PID。 我将“USBStOR ...”链接存储为字符串,并将其用于第二个函数以查找DiskDrive的相关PNPEntity。这导致正确的DiskPartition以及LogicalDisk =驱动器号。
希望不会迟到,这两个功能都会对你有帮助!
第一功能:
public void FindPath()
{
foreach (ManagementObject entity in new ManagementObjectSearcher("select * from Win32_USBHub Where DeviceID Like '%VID_XXXX&PID_XXXX%'").Get())
{
Entity = entity["DeviceID"].ToString();
foreach (ManagementObject controller in entity.GetRelated("Win32_USBController"))
{
foreach (ManagementObject obj in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_USBController.DeviceID='" + controller["PNPDeviceID"].ToString() + "'}").Get())
{
if(obj.ToString().Contains("DeviceID"))
USBobjects.Add(obj["DeviceID"].ToString());
}
}
}
int VidPidposition = USBobjects.IndexOf(Entity);
for (int i = VidPidposition; i <= USBobjects.Count; i++ )
{
if (USBobjects[i].Contains("USBSTOR"))
{
Secondentity = USBobjects[i];
break;
}
}
}
&GT;
第二功能:
public void GetDriveLetter()
{
foreach (ManagementObject drive in new ManagementObjectSearcher("select * from Win32_DiskDrive").Get())
{
if (drive["PNPDeviceID"].ToString() == Secondentity)
{
foreach (ManagementObject o in drive.GetRelated("Win32_DiskPartition"))
{
foreach (ManagementObject i in o.GetRelated("Win32_LogicalDisk"))
{
Console.WriteLine("Disk: " + i["Name"].ToString());
}
}
}
}
}
&GT;
答案 1 :(得分:2)
非常感谢@Michaela提供了非常有帮助的答案,但我认为这段代码更短
public void FindPath()
{
ManagementObjectSearcher entity = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject obj in entity.Get())
{
if (obj["PNPDeviceID"].ToString().Contains("USBSTOR"))
{
if (!USBobjects.Contains(obj["PNPDeviceID"].ToString()))
USBobjects.Add(obj["PNPDeviceID"].ToString());
}
}
}
我有GetDriveLetter()
方法的另一个问题,有时编译foreach
行需要很长时间。有人可以告诉我原因吗?
答案 2 :(得分:-1)
DriveInfo[] ListDrives = DriveInfo.GetDrives();
foreach (DriveInfo Drive in ListDrives)
{
if (Drive.DriveType == DriveType.Removable)
{
try
{
Console.WriteLine(Drive.Name);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}