You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何排除映射网络驱动器评估LogicalDisk实例并跨平台获取系统盘序列号

解决方案

1. Windows平台高效获取系统盘对应硬盘序列号

核心优化:跳过网络驱动器,直接定位系统盘关联路径

无需扫描所有Win32_LogicalDisk实例,通过精准查询减少不必要的遍历:

  • 第一步:通过Win32_OperatingSystem获取系统盘符(不受C盘限制)
  • 第二步:仅查询该盘符对应的本地逻辑磁盘(过滤DriveType=3,排除网络驱动器)
  • 第三步:通过WMI关联类映射到物理磁盘,获取序列号

示例代码片段:

// 获取系统盘符
var osQuery = new ManagementObjectSearcher("SELECT SystemDrive FROM Win32_OperatingSystem");
var systemDrive = osQuery.Get().Cast<ManagementObject>().First()["SystemDrive"].ToString();

// 查询对应本地逻辑磁盘
var diskQuery = new ManagementObjectSearcher($"SELECT * FROM Win32_LogicalDisk WHERE DeviceID='{systemDrive}' AND DriveType=3");
var logicalDisk = diskQuery.Get().Cast<ManagementObject>().FirstOrDefault();

if (logicalDisk != null)
{
    // 关联到磁盘分区
    var partitionQuery = new ManagementObjectSearcher($"ASSOCIATORS OF {{Win32_LogicalDisk.DeviceID='{systemDrive}'}} WHERE AssocClass=Win32_LogicalDiskToPartition");
    var partition = partitionQuery.Get().Cast<ManagementObject>().FirstOrDefault();

    if (partition != null)
    {
        // 关联到物理磁盘
        var driveQuery = new ManagementObjectSearcher($"ASSOCIATORS OF {{Win32_DiskPartition.DeviceID='{partition["DeviceID"]}'}} WHERE AssocClass=Win32_DiskDriveToDiskPartition");
        var diskDrive = driveQuery.Get().Cast<ManagementObject>().FirstOrDefault();

        if (diskDrive != null)
        {
            var serialNumber = diskDrive["SerialNumber"]?.ToString().Trim();
            // 使用获取到的序列号
        }
    }
}

额外优化:设置WMI查询超时

给查询添加超时限制,避免意外阻塞:

var options = new ConnectionOptions();
options.Timeout = TimeSpan.FromSeconds(10);
var scope = new ManagementScope("root\\CIMV2", options);
var query = new ObjectQuery($"SELECT * FROM Win32_LogicalDisk WHERE DeviceID='{systemDrive}' AND DriveType=3");
var searcher = new ManagementObjectSearcher(scope, query);

2. 跨平台兼容实现方案

Linux

  • 步骤1:从/proc/mounts中过滤根分区(挂载点为/)的设备路径
  • 步骤2:通过lsblk命令获取对应物理磁盘的序列号,示例命令:
# 获取根分区设备
root_part=$(awk '$2 == "/" {print $1}' /proc/mounts)
# 提取物理磁盘路径
disk=$(echo $root_part | sed 's/[0-9]*$//')
# 获取序列号
serial=$(lsblk -no SERIAL $disk)
  • 替代方案:读取/sys/block/[disk]/serial文件(部分系统支持)

Android

  • 基于Linux内核,可参考Linux方案,需注意权限:
    • 需申请READ_EXTERNAL_STORAGE或更高权限(Android 10+需适配Scoped Storage)
    • 通过shell命令或StorageManager API获取信息,示例Java代码:
try {
    Process process = Runtime.getRuntime().exec("lsblk -no SERIAL /dev/block/sda");
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String serial = reader.readLine().trim();
} catch (IOException e) {
    e.printStackTrace();
}

iOS

  • 受沙盒限制,公开API无法直接获取硬件序列号;企业级应用可使用IOKit框架:
#import <IOKit/IOKit.h>

NSString* getSystemDiskSerial() {
    io_service_t diskIterator = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(kIODeviceTreePlane), NULL);
    io_service_t diskService;
    NSString* serial = nil;
    while ((diskService = IOIteratorNext(diskIterator))) {
        CFTypeRef serialRef = IORegistryEntryCreateCFProperty(diskService, CFSTR("serial-number"), kCFAllocatorDefault, 0);
        if (serialRef) {
            serial = (__bridge NSString*)serialRef;
            CFRelease(serialRef);
            break;
        }
        IOObjectRelease(diskService);
    }
    IOObjectRelease(diskIterator);
    return serial;
}

注意:使用非公开API可能导致App Store审核不通过。

3. 通用识别系统盘

Windows

直接读取Win32_OperatingSystem的SystemDrive属性,该属性返回系统安装所在的盘符(不受固定盘符限制)。

Linux & Android

根目录/所在的分区对应的物理磁盘即为系统盘,通过/proc/mounts或mount命令过滤挂载点为/的条目,解析设备路径后关联到物理磁盘。

iOS

通过IOKit查询启动盘信息,或通过NSFileManager获取系统目录所在卷的信息,再关联到磁盘序列号。

内容的提问来源于stack exchange,提问作者J Collins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:10:33