WMI - 直接访问 Win32_OperatingSystem 的单例实例

Posted

技术标签:

【中文标题】WMI - 直接访问 Win32_OperatingSystem 的单例实例【英文标题】:WMI - Directly accessing the singleton instance of Win32_OperatingSystem 【发布时间】:2010-09-08 13:04:29 【问题描述】:

我无法直接访问通过 WMI 公开的 Win32_OperatingSystem 管理类。

这是一个单例类,我很确定“Win32_OperatingSystem=@”是获取单例实例的正确路径语法。

调用 InvokeMethod 会产生列在问题底部的异常,访问 ClassPath 属性也会产生异常(注释行)。

我做错了什么?

[我知道我可以使用 ManagementObjectSearcher/ObjectQuery 来返回 Win32_OperatingSystem 的集合(它只包含一个),但由于我知道它是一个单例,所以我想直接访问它。]


ManagementScope cimv2 = InitScope(string.Format(@"\\0\root\cimv2", this.Name));

ManagementObject os = new ManagementObject(
    cimv2,
    new ManagementPath("Win32_OperatingSystem=@"),
    new ObjectGetOptions());

//ManagementPath p = os.ClassPath;

os.InvokeMethod("Reboot", null);

System.Management.ManagementException 被捕获 Message="无效的对象路径" 来源="系统管理" 堆栈跟踪: 在 System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus 错误代码) 在 System.Management.ManagementObject.Initialize(布尔 getObject) 在 System.Management.ManagementBaseObject.get_wbemObject() 在 System.Management.ManagementObject.get_ClassPath() 在 System.Management.ManagementObject.GetMethodParameters(字符串方法名,ManagementBaseObject& inParameters,IWbemClassObjectFreeThreaded& inParametersClass,IWbemClassObjectFreeThreaded& outParametersClass) 在 System.Management.ManagementObject.InvokeMethod(String methodName, Object[] args)


感谢您的回复。

尼克 - 我不知道该怎么做 :)

Uros - 因为this MSDN 页面,我觉得这是一个单例类。此外,在 WBEMTest 实用程序中打开类会显示 this。


实例对话框显示:“1 个对象”和“最大批次:1”在这些字段中并列出“Win32_OperatingSystem=@”

已验证 ManagementScope 可以正常工作,所以我不知道发生了什么。我是 WMI 新手,但这似乎是最简单的用例之一!

【问题讨论】:

【参考方案1】:

我刚刚尝试过这个运行良好的简单应用程序

using System;
using System.Management;

namespace WmiPlay

    class Program
    
        static void Main(string[] args)
        
            try
            
                ManagementScope cimv2 = new ManagementScope(@"\\.\root\cimv2");
                ManagementObject os = new ManagementObject(cimv2, new ManagementPath("Win32_OperatingSystem=@"), new ObjectGetOptions());
                Console.Out.WriteLine(os);
            
            catch (Exception ex)
            
                Console.Error.WriteLine(ex);
            
        
    

看看这对你有用吗?我确实在 Visual Studio 中运行过它,我通常在 Vista x64 下以管理员身份运行。

【讨论】:

【参考方案2】:

邓肯写道:

实例对话框显示:“1 个对象”和“最大批次:1”在这些字段中并>列出“Win32_OperatingSystem=@”

它确实看起来应该可以工作。您可以使用另一个单例类来测试您的代码,例如:

"Win32_WmiSetting=@"

看看你是否仍然得到异常。

【讨论】:

【参考方案3】:

我可能会构造一个查询来获取 Primary = true 的实例。我有一段时间没有使用 Win32_OperatingSystem,但我似乎记得获得了多个实例,并且当前启动的那个的 Primary 等于 true。

【讨论】:

【参考方案4】:

哇,世界正在改变。抱歉,我不知道您使用的是 Vista。如您所见here,Windows XP 中的情况有所不同。那么,当您单击“实例”按钮时会发生什么?

【讨论】:

【参考方案5】:

Win32_OperatingSystem 不是单例类 - 如果您检查它的限定符,您会发现没有为它定义单例限定符,因此您必须使用 ManagementObjectSearcher.Get() 或 ManagementClass.GetInstances() 即使该类只有一个实例。 Win32_OperatingSystem 的关键属性是 Name,所以有一个选项可以直接获取实例,使用

ManagementObject OS = new ManagementObject(@"Win32_OperatingSystem.Name='OSname'")

但根据我的经验,OSName 总是类似于:

"Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1"

所以使用 ManagementObjectSearcher 可能是最简单的解决方案。

【讨论】:

【参考方案6】:

我不能 100% 确定答案,但您是否尝试过使用反射器来查看 ManagementObjectSearcher 的作用?它可能会给你一些关于你做错了什么的线索。

【讨论】:

以上是关于WMI - 直接访问 Win32_OperatingSystem 的单例实例的主要内容,如果未能解决你的问题,请参考以下文章

wmi.WMI().Win32_ComputerSystem()

wmi使用的win32类库名

WMI使用的WIN32_类库名

Win32_Printer 远程 WMI 查询真的很慢

WMI Win32_OperatingSystem OSArchitecture 字段导致异常

WMI Win32_BaseBoard 序列号