如何通过序列号获取 CD/DVD-ROM 盘符

How to get CD/DVD-ROM Drive Letter by Serial Number

我正在尝试使用他们提供的 PTRobot API 与 Primera 光盘复制器进行交互。他们的 API return 有关机器人中记录器驱动器的信息,但缺少的关键部分是驱动器号。

他们所做的信息 return 是型号名称、固件和序列号。

我需要区分一个单元中的多个相同驱动器,序列号是提供的唯一唯一值。

我发现了很多相反的示例(使用驱动器号获取型号或序列号),但是 none 看起来可以翻转使用。

您可以编写一个例程,通过检查每个驱动器来构建按序列号散列的驱动器字典。那么您就拥有了使用 PTRobot api.

所需的缺失信息

编辑:

From a search for c# getting a serial number for a drive

Code from an example of how to get the hard drive serial number. UNtested as I no longer have a windows device

以下内容可以帮到您:

searcher = new
ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");

int i = 0;
foreach(ManagementObject wmi_HD in searcher.Get())
{
 // get the hard drive from collection
// using index
HardDrive hd = (HardDrive)hdCollection[i];

// get the hardware serial no.
if (wmi_HD["SerialNumber"] == null)
 hd.SerialNo = "None";
else
 hd.SerialNo = wmi_HD["SerialNumber"].ToString();

++i;
}

听起来您可以获取序列号与您正在搜索的驱动器相匹配的驱动器,然后获取它的分区,并为每个分区从逻辑驱动器获取它的驱动器号。

例如:

using System.Collections.Generic
using System.Management;

public static List<string> GetDriveLettersForSerialNumber(string driveSerialNumber)
{        
    var results = new List<string>();
    if (driveSerialNumber == null) return results;

    var drive = new ManagementObjectSearcher(
        "SELECT DeviceID, SerialNumber, Partitions FROM Win32_DiskDrive").Get()
        .Cast<ManagementObject>()
        .FirstOrDefault(device =>
            device["SerialNumber"].ToString().Trim()
                .Equals(driveSerialNumber.Trim(), StringComparison.OrdinalIgnoreCase));

    if (drive == null) return results;

    var partitions = new ManagementObjectSearcher(
        $"ASSOCIATORS OF {{Win32_DiskDrive.DeviceID='{drive["DeviceID"]}'}} " +
        "WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get();

    foreach (var partition in partitions)
    {
        var logicalDrives = new ManagementObjectSearcher(
            "ASSOCIATORS OF {{Win32_DiskPartition.DeviceID=" + 
            $"'{partition["DeviceID"]}'}} " +
            "WHERE AssocClass = Win32_LogicalDiskToPartition").Get();

        foreach (var logicalDrive in logicalDrives)
        {
            var volumes = new ManagementObjectSearcher(
                "SELECT Name FROM Win32_LogicalDisk WHERE " +
                $"Name='{logicalDrive["Name"]}'").Get().Cast<ManagementObject>();

            results.AddRange(volumes.Select(v => v["Name"].ToString()));
        }
    }

    return results;
}

对于 CDROM 来说似乎更容易 - "Id" 和 "SerialNumber" 都包含在同一个对象中:

public static string GetDriveLetterForCDROMSerialNumber(string driveSerialNumber)
{
    return new ManagementObjectSearcher(
        "SELECT Id, SerialNumber FROM Win32_CDROMDrive").Get()
        .Cast<ManagementObject>()
        .Where(drive => drive.GetPropertyValue("SerialNumber").ToString().Trim()
            .Equals(driveSerialNumber.Trim(), StringComparison.OrdinalIgnoreCase))
        .Select(drive => drive.GetPropertyValue("Id").ToString())
        .FirstOrDefault() ?? "Unknown";
}

感谢您的建议并指导我使用 WMI 查询。这只是找到哪一个有我需要的信息的问题 (Win32_CDROMDrive)。这是我的工作代码:

public static string GetDriveLetter(string serialNum){
    if (serialNum != null)
    {
        var moc = new ManagementObjectSearcher("SELECT SerialNumber, Drive FROM Win32_CDROMDrive");

        foreach(var mo in moc.Get())
        {
            string driveSerial = (string)mo.GetPropertyValue("SerialNumber");
            if (driveSerial != null)
            {
                if (driveSerial.Trim().Equals(serialNum.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    return (string)mo.GetPropertyValue("Drive");
                }
            }
        }
    }
    return "Unknown";
}