使用关联器从 MSFT_Disk 获取 MSFT_Partition

Getting MSFT_Partition from MSFT_Disk using Associators

我正在尝试从 MSFT_Disk 对象中获取 MSFT_Partitions 的列表并循环遍历它们。 这是我到目前为止一直在使用的代码,但它总是输出一个 System.Management.ManagementException: 'Invalid query ' 异常。

这是我目前使用的代码:

public static void GetDiskInfo() {
    var rawDiskInfos = new ManagementObjectSearcher("root\Microsoft\Windows\Storage", "SELECT * FROM MSFT_Disk");
    foreach(var rawDiskInfo in rawDiskInfos.Get()) {
        Console.WriteLine(rawDiskInfo["FriendlyName"]);
        GetPartitionInfo(rawDiskInfo["ObjectId"]);
    }
}

public static void GetPartitionInfo(object objectId) {
    ManagementScope scope = new ManagementScope("\\.\ROOT\Microsoft\Windows\Storage");

    var query = new ObjectQuery("ASSOCIATORS OF {MSFT_Disk.ObjectId=\"" + objectId + "\"} WHERE AssocClass = MSFT_DiskToPartition");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
    ManagementObjectCollection queryCollection = searcher.Get();

    foreach(var partiton in queryCollection) {
        Console.WriteLine(partiton["Guid"]);
    }
}

我已经尝试了很多在网上找到的解决方案,但所有解决方案都导致了相同的异常。

非常感谢您的帮助!

您在互联网上找到的大多数查询都不会这样做,但在一般情况下,您必须转义传递给 WQL 查询的原始字符串(在您的情况下 objectId 包含特殊字符),使用 backslash character,方法如下:

public static string EscapeWql(string text)
{
    if (text == null)
        return null;

    var sb = new StringBuilder(text.Length);
    foreach (var c in text)
    {
        if (c == '\' || c == '\'' || c == '"')
        {
            sb.Append('\');
        }
        sb.Append(c);
    }
    return sb.ToString();
}

所以您的方法现在应该如下所示:

public static void GetPartitionInfo(object objectId)
{
    var scope = new ManagementScope(@"root\Microsoft\Windows\Storage");
    var query = new ObjectQuery("ASSOCIATORS OF {MSFT_Disk.ObjectId=\"" + EscapeWql((string)objectId) + "\"} WHERE AssocClass = MSFT_DiskToPartition");
    using (var searcher = new ManagementObjectSearcher(scope, query))
    {
        using (var queryCollection = searcher.Get())
        {
            foreach (var partition in queryCollection)
            {
                Console.WriteLine(partition["Guid"]);
            }
        }
    }
}

PS:不要忘记在 IDisposable 类.

上使用语句