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

使用Win32_DiskDrive识别存储卡及分区的C#技术问题

Fixing WMI Disk Drive Issues with Laptop Card Readers

Hey there, let's tackle those WMI disk drive quirks you're facing with your laptop's built-in card reader— I've wrestled with similar problems before, so here's how to resolve each of your issues:

1. Handling Empty InterfaceType for Memory Cards

You already have a fallback to MediaType in your code, which is the right call— many card reader devices don't report an InterfaceType via WMI, so falling back makes sense. Let's tweak that line to add an extra safety check in case MediaType is also null (though rare):

string s_interface = info["InterfaceType"]?.ToString() ?? info["MediaType"]?.ToString() ?? "Unknown";

This uses null-conditional operators to avoid null reference exceptions, and defaults to "Unknown" if both properties are missing.

2. Getting Memory Card Serial Numbers

The SerialNumber property from Win32_DiskDrive often returns null for removable media like SD cards in built-in readers. This is because the reader hardware might not expose the card's serial number through WMI. Here are two workarounds:

  • Fallback to Partition Volume Serial Number: If you don't need the physical card's serial, you can grab the VolumeSerialNumber from the associated Win32_LogicalDisk object. Note this is the partition's serial, not the card's, but it's better than nothing.
  • Use Win32_PhysicalMedia Association: Try associating Win32_DiskDrive with Win32_PhysicalMedia— some devices report the serial here instead. Add this code after getting the disk drive info:
    string s_serialnumber = "No serial number";
    foreach (ManagementObject media in info.GetRelated("Win32_PhysicalMedia"))
    {
        if (media["SerialNumber"] != null)
        {
            s_serialnumber = media["SerialNumber"].ToString().Trim();
            break;
        }
    }
    
    Keep in mind this still might not work for all readers, depending on hardware support.

3. Reading Array-Type Properties Like Capabilities

When you see System.UInt16[] in your logs, that means the property is an array— you need to iterate over its elements and map them to human-readable values using the WMI enum definitions. For Capabilities, the Win32_DiskDrive class uses the DiskDriveCapabilities enum, where each value corresponds to a feature (e.g., 1 = Random Access, 2 = Supports Writing).

Here's how to format this array into a readable string:

if (property.Value is Array arrayVal)
{
    var capabilityDescriptions = new Dictionary<uint, string>
    {
        { 1, "Random Access" },
        { 2, "Supports Writing" },
        { 3, "Supports Removable Media" },
        { 4, "Hardware Raid" },
        { 5, "Supports Password Protection" },
        { 6, "Supports Dual-Sided Media" }
        // Add more from the DiskDriveCapabilities enum as needed
    };

    var capabilityStrings = new List<string>();
    foreach (var item in arrayVal)
    {
        if (item is uint capability && capabilityDescriptions.ContainsKey(capability))
        {
            capabilityStrings.Add(capabilityDescriptions[capability]);
        }
        else
        {
            capabilityStrings.Add(item.ToString());
        }
    }
    Global.LogMessage($"[{property.Name}] = '{string.Join(", ", capabilityStrings)}'", 1);
}
else
{
    Global.LogMessage($"[{property.Name}] = '{property.Value ?? "null"}'", 1);
}

This checks if the property value is an array, then maps each element to its description. You can expand the dictionary with all values from the official DiskDriveCapabilities enum for full coverage.

Modified Full Code Example

Here's your updated function incorporating all these fixes:

void GetFullInfoDiskDrives() {
    Global.LogMessage("************** GetFullInfoDiskDrives() Getting complete info from all disk drives ", 1);
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
    foreach (ManagementObject info in searcher.Get()) {
        // Lets print all the properties per disk
        PropertyDataCollection properties = info.Properties;
        // display the properties
        Global.LogMessage("----------------- Properties for the disk " + info["Model"].ToString(),1);
        
        // Dictionary for Capabilities enum descriptions
        var capabilityDescriptions = new Dictionary<uint, string>
        {
            { 1, "Random Access" },
            { 2, "Supports Writing" },
            { 3, "Supports Removable Media" },
            { 4, "Hardware Raid" },
            { 5, "Supports Password Protection" },
            { 6, "Supports Dual-Sided Media" }
        };

        foreach (PropertyData property in properties) {
            string valueStr;
            if (property.Value is Array arrayVal)
            {
                var capabilityStrings = new List<string>();
                foreach (var item in arrayVal)
                {
                    if (item is uint capability && capabilityDescriptions.ContainsKey(capability))
                    {
                        capabilityStrings.Add(capabilityDescriptions[capability]);
                    }
                    else
                    {
                        capabilityStrings.Add(item.ToString());
                    }
                }
                valueStr = string.Join(", ", capabilityStrings);
            }
            else
            {
                valueStr = property.Value?.ToString() ?? "null";
            }
            Global.LogMessage($"[{property.Name}] = '{valueStr}'", 1);
            foreach (QualifierData q in property.Qualifiers) {
                Global.LogMessage($" -{q.Name}- = '{q.Value}'", 1);
            }
        }
        string s = "";
        string s_model = info["Model"]?.ToString() ?? "Unknown Model";
        string s_interface = info["InterfaceType"]?.ToString() ?? info["MediaType"]?.ToString() ?? "Unknown";
        string s_serialnumber = "No serial number";
        
        // Try getting serial from Win32_PhysicalMedia
        foreach (ManagementObject media in info.GetRelated("Win32_PhysicalMedia"))
        {
            if (media["SerialNumber"] != null)
            {
                s_serialnumber = media["SerialNumber"].ToString().Trim();
                break;
            }
        }

        Global.LogMessage($"Disk detected (Model: {s_model} | Interface: {s_interface} | Serial#: {s_serialnumber}",1);
        foreach (ManagementObject o in info.GetRelated("Win32_DiskPartition"))
            foreach (ManagementObject i in o.GetRelated("Win32_LogicalDisk"))
                s += i["Name"] + " ";
        Global.LogMessage("Logical disks: " + (s == "" ? "None" : s),1);
    }
}

A quick note: WMI behavior can vary between hardware vendors and Windows versions, so some edge cases might still exist, but these changes should cover most common issues with built-in card readers.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:16:30