【问题标题】:How to get CD/DVD-ROM Drive Letter by Serial Number如何通过序列号获取 CD/DVD-ROM 驱动器号
【发布时间】:2018-12-07 22:43:09
【问题描述】:

我正在尝试使用 Primera Disc Duplicator 提供的 PTRobot API 与其交互。他们的 API 返回有关机器人中记录器驱动器的信息,但缺少的关键部分是驱动器号。

他们返回的信息是型号名称、固件和序列号。

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

我发现了很多相反的例子(使用驱动器号来获取型号或序列号),但没有一个看起来可以翻转以供我使用。

【问题讨论】:

  • 只需遍历所有驱动器并找到它们的序列号。然后将其与您的结果集交叉匹配。我不会想象你有超过 10 个驱动器,所以性能根本不是问题
  • @Steve 说得有道理,但我怎么能循环通过驱动器来获取序列号? DriveInfo.GetDrives() 不提供此功能。
  • 除非我有误解,否则您会意识到每个物理驱动器可以有多个驱动器号,对吧?驱动器号用于分区...
  • @RufusL 这些是刻录机驱动器。 CD/DVD-ROM。我意识到这些在技术上可以被分区,但不是通常做的事情,或者在大多数操作系统中得到很好的支持

标签: c# drive


【解决方案1】:

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

例如:

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";
}

【讨论】:

  • 不幸的是,这仅适用于硬盘驱动器,而我正在尝试使用 CD/DVD-ROM 驱动器
  • 看起来你已经找到了答案,但由于我刚刚做了研究,我想我也会更新这个。
  • 当然可以,但我很感激帮助我指出了这个方向。我已接受您的回答,因为它更完整并为硬盘提供了额外的方法
【解决方案2】:

您可以编写一个例程,通过检查每个驱动器来构建按序列号散列的驱动器字典。然后,您就有了使用 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;
}

【讨论】:

  • 您能否提供任何示例代码或指出正确的方向以获取驱动器的序列号? DriveInfo.GetDrives() 不提供此信息...
  • 已添加。我将在本周晚些时候添加一些代码来完成它。您能否添加您迄今为止尝试过的代码。我无法轻松访问 Windows 设备。
  • 这看起来很有希望,但据我所知,Win32_PhysicalMedia 没有提供到驱动器号的映射...实际上,它似乎只返回一个序列号和标签,例如“\ \.\CDROM2",所以我不确定如何在不执行另一个查询和比较的情况下将其与驱动器号联系起来
【解决方案3】:

感谢您的建议并指出我使用 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";
}

【讨论】:

  • 不错!我正要发帖:return new ManagementObjectSearcher("SELECT Id, SerialNumber FROM Win32_CDROMDrive").Get().Cast&lt;ManagementObject&gt;().Where(drive =&gt; drive.GetPropertyValue("SerialNumber").ToString().Trim().Equals(driveSerialNumber.Trim(), StringComparison.OrdinalIgnoreCase)).Select(drive =&gt; drive.GetPropertyValue("Id").ToString()).FirstOrDefault() ?? "Unknown";
猜你喜欢
  • 1970-01-01
  • 2017-09-28
  • 2012-09-07
  • 2018-07-11
  • 2011-07-12
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 2017-02-22
相关资源
最近更新 更多