views:

1761

answers:

9

Hi - I've having trouble directly accessing the Win32_OperatingSystem management class that is exposed via WMI.

It is a singleton class, and I'm pretty certain "Win32_OperatingSystem=@" is the correct path syntax to get the instance of a singleton.

The call to InvokeMethod produces the exception listed at the bottom of the question, as does accessing the ClassPath property (commented line).

What am I doing wrong?

[I'm aware that I can use ManagementObjectSearcher/ObjectQuery to return a collection of Win32_OperatingSystem (which would contain only one), but since I know it is a singleton, I want to access it directly.]


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 was caught Message="Invalid object path " Source="System.Management" StackTrace: at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode) at System.Management.ManagementObject.Initialize(Boolean getObject) at System.Management.ManagementBaseObject.get_wbemObject() at System.Management.ManagementObject.get_ClassPath() at System.Management.ManagementObject.GetMethodParameters(String methodName, ManagementBaseObject& inParameters, IWbemClassObjectFreeThreaded& inParametersClass, IWbemClassObjectFreeThreaded& outParametersClass) at System.Management.ManagementObject.InvokeMethod(String methodName, Object[] args)

+1  A: 

I'm not 100% sure of the answer, but have you tried using reflector to look at what ManagementObjectSearcher does? It may give you some clue as to what you are doing wrong.

Nick R
+1  A: 

Win32_OperatingSystem is not a singleton class - if you check its qualifiers, you'll see that there is no Singleton qualifier defined for it, so you'll have to use ManagementObjectSearcher.Get() or ManagementClass.GetInstances() even though there is only one instance of the class. Win32_OperatingSystem key property is Name, so there is an option to get the instance directly, using

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

but in my experience, OSName is always something like:

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

so using ManagementObjectSearcher is probably the easiest solution.

Uros Calakovic
A: 

Thanks for the replies.

Nick - I don't know how to go about doing that :)

Uros - I was under the impression that it was a singleton class because of this MSDN page. Also, opening the class in the WBEMTest utility shows this.

frou
A: 

Wow, the world is changing. Sorry, I didn't realize you were using Vista. As you can see here, things were different back in Windows XP. So, what happens when you click the "Instances" buton?

Uros Calakovic
+1  A: 

I would probably construct a query that gets the instance where Primary = true. I haven't used Win32_OperatingSystem in a while, but I seem to remember getting multiple instances, and the one that was currently booted had Primary equal to true.

dcstraw
A: 

The instances dialog shows: "1 objects" and "max. batch: 1" in those fields and lists "Win32_OperatingSystem=@"

The ManagementScope is verified as working, so I don't know what's up. I'm a WMI novice, but this seems like one of the simplest use cases!

frou
+1  A: 

Duncan wrote:

The instances dialog shows: "1 objects" and "max. batch: 1" in those fields and >lists "Win32_OperatingSystem=@"

It sure looks like it should work. You could test your code with another singleton class, like:

"Win32_WmiSetting=@"

and see if you still get the exception.

Uros Calakovic
+2  A: 

I've just tried this simple app that worked ok

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);
            }
        }
    }
}

See if this works for you? I did run it in Visual Studio which I normally run as administrator under Vista x64.

Nick R
+1  A: 

Thanks, Nick. Yep, that does work in Vista, but not in XP.

I just realised that I've been confused over which of the computers I'm connecting to are XP and which are Vista. So it is all down to the sneaky change Uros mentioned!

I'll update the question title. Thanks, everyone.

frou