首页 > 解决方案 > 使用关联器从 MSFT_Disk 获取 MSFT_Partition

问题描述

我正在尝试MSFT_PartitionsMSFT_Disk对象中获取列表并遍历它们。这是我到目前为止一直在使用的代码,但它总是输出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"]);
    }
}

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

非常感谢您的帮助!

标签: c#winapiwmi

解决方案


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

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类上使用语句。


推荐阅读