SgDotNet
Singapore Professional .NET User Group -For Cool Developers

WMI: ManagementBaseObject to ManagementObject

rated by 0 users
This post has 9 Replies | 2 Followers

Top 10 Contributor
Posts 2,403
icelava Posted: 06-15-2005 1:44 AM
Simple WQL query

this.managementEventWatcher1.Query = new System.Management.EventQuery("SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE PreviousInstance ISA \"Win32_Processor\" AND TargetInstance ISA \"Win32_Processor\" AND TargetInstance.LoadPercentage < 30");
this.managementEventWatcher1.Scope = new System.Management.ManagementScope("\\\\icelava\\root\\CIMV2");


Now the EventWatcher is hooked up with an event handler managementEventWatcher1_EventArrived(), and by unpackaging the EventArrivedEventArgs.NewEvent object, which is a ManagementBaseObject, within it exists the PreviousInstance and TargetInstance objects, which should represent instances of the Win32_Processor class.

But, I am unable to cast that very NewEvent["TargetInstance"] into a ManagementObject object - invalid cast specified. Well, since I am not querying for the Win32_Processor class per se (which i should then have to use ManagementClass) but a live object of that class, i don't understand why casting to ManagementObject fails and must have it remain as a ManagementBaseObject. Any ideas?

The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

Top 10 Contributor
Posts 1,221

You can't downcast from a base class to a derived class.

That should be your problem.

Regards, triplez ------------------------------ http://triplez.mine.nu/blogs
Top 10 Contributor
Posts 2,403
How does such a rule apply? Meaning I cannot downcast from Object back into its original type either should I have stored items in an ArrayList?

From all the WMI samples I have come across the expected object type to work with is ManagementObject (or ManagementClass if dealing with a WMI class), and not the base class ManagementBaseObject. If this is proper behaviour, then there is something that had the WMI provider instantiating the resultant objects only as ManagementBaseObject, conditions which I have no knowledge of.

The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

Top 10 Contributor
Posts 1,221

The rule only applies when you go from a base class up to a derived class.

Why downcasting from Object back to the original type works is becoz it uses unboxing, instead of casting. which retains the object's original structure type. And don't try casting from ManagementBaseObject -> Object -> ManagementClass because boxing will throw an exception coz of type mismatch.

Whereas when you downcast from a base class to a derived class, your base class does not have the additional information of the derived class to be created as a new derived type. That's the problem. That's where interfaces come in. Interfaces guarantees that you have those methods within your objects, else it'll throw an exception before you even start using it.

I don't know much about WMI provider, but the differences I see from ManagementClass and ManagementObject to ManagementBaseObject is very small. Unless you're meant to work in ManagementClass, I'm sure the ManagementBaseObject will provide you with everything you need.

If you can show some code, and which class/method you're using, maybe I can help a bit. Coz I've never used WMI before.

Regards, triplez ------------------------------ http://triplez.mine.nu/blogs
Top 10 Contributor
Posts 2,403
 triplez wrote:
Whereas when you downcast from a base class to a derived class, your base class does not have the additional information of the derived class to be created as a new derived type. That's the problem. That's where interfaces come in. Interfaces guarantees that you have those methods within your objects, else it'll throw an exception before you even start using it.
You are assuming the WMI provider instantiated the object as a ManagementBaseObject right from the start. From the behaviour observed, that is the case. My question is pointing to the evidence that all materials (at least consumed so far) suggest the use of ManagementObject when working with instances and ManagementClass when working with classes, so I don't expect to be working with ManagementBaseObject, and expect it to be instantiated to the derived type according to my query.

Meaning, if I queried specifically for Win32_Processor as a class, then it should be ManagementClass. In the actual case, I queried for a working instance, so I expected ManagementObject. But my expectations don't coincide with reality.

The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

Top 10 Contributor
Posts 1,221

From what I see in the e.NewEvent sample code, they do still cast it to ManagementBaseObject.

They have to throw to the event as a ManagementBaseObject is because the NewEvent might be a ManagementObject or a ManagementClassObject, and you can't really determine whicch one it is. They didn't provide 2 seperate EventArrivedEventArg types like EventArrivedEventArgClassObject and EventArrivedEventArgObject should be because they didn't want to complicate things, and you should be able to do whatever you need within the boundaries of ManagementBaseObject.

It's actually correct design on their part, where it comes from a C++ background. What you should expect is the base class, because it is guaranteed from that object that all methods MUST and WILL have an implementation from the ManagementBaseObject.

Whereas if they followed the design above, it becomes cumbersome and needs to add more code as newer derived classes get created (if so).

A better way would be to use Interfaces, but this is Interop code, and interfaces aren't really fully supported.

Regards, triplez ------------------------------ http://triplez.mine.nu/blogs
Top 10 Contributor
Posts 2,403
I already knew, and you can see the point of using ManagementBaseObject is to accomodate both the possibilities of ManagementObject and ManagementClass being the real object. What I am pointing out here is the expectation of the underlying WMI provider to have instantiated the appropriate object type and upcast to ManagementBaseObject for event passage and leave the downcasting to me; I know what I queried for - even if the event logic doesn't, the point of origin (WMI provider) would - so I expect a more specific derived-type in return.

The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

Top 10 Contributor
Posts 1,221

Your case is similar to wanting to store multiple types of data in a collection class. You know which data is what type in the collection, but why does a collection class only able to return the base class? (don't talk about objects. Custom collections).

When you pass it into the collection, and cast it as a base class (to support all derived types in the collection), basically you lose the additional "data" from the derived class, and the derived class fits nicely into the base class structure, anything additional is chopped off and removed.

Obviously when you want to downcast it back to the derived type, you're not able to, because that additional "data" is already lost somewhere in data-dumping grounds.

That's one of the reasons why .NET and Java came up with boxing. Boxing casts it to an object class, which RETAINS these additional "data". Therefore you're able to unbox it again.

Regards, triplez ------------------------------ http://triplez.mine.nu/blogs
Top 10 Contributor
Posts 2,403
 triplez wrote:
When you pass it into the collection, and cast it as a base class (to support all derived types in the collection), basically you lose the additional "data" from the derived class, and the derived class fits nicely into the base class structure, anything additional is chopped off and removed.
By your explanation, this would fail

ManagementClass wmiClass = new ManagementClass(@"\\.\root\CIMV2:Win32_LogicalDisk");
MessageBox.Show(wmiClass.ClassPath.ClassName + " " + wmiClass.Path);

ManagementObject wmiObject = (ManagementObject)wmiClass;
MessageBox.Show(wmiObject.ClassPath.ClassName + " " + wmiObject.Path);
ManagementBaseObject wmiBaseObject = (ManagementBaseObject)wmiObject;
MessageBox.Show(wmiBaseObject.ClassPath.ClassName + " has no Path property.");

ManagementClass anotherClass = (ManagementClass)wmiBaseObject;
MessageBox.Show(anotherClass.ClassPath.ClassName + " " + anotherClass.Path);


But it doesn't; works fine as expected. I have never read any material that states a derived object gets physically "truncated" into its base type object in an irreversible manner, never to live and breathe as its original type again. The object remains as its whole self in memory, only the [type] pointer referencing the object views it differently.

However this has gone off-topic. The main issue here is the System.Management namespace group does not bother to differentiate between a WMI instance or class and just instantiates as ManagementBaseObject prior to event raise, rather than the more specialised derived types.

The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

Top 10 Contributor
Posts 1,221

Hmm, yes, sorry. My bad. I'm wrong. :P

Anyway, maybe you can try using "as" keyword... or for testing purposes, use "is" to test if it's from a derived type.

It might have done something to the type or something. LOL. :P

Regards, triplez ------------------------------ http://triplez.mine.nu/blogs
Page 1 of 1 (10 items) | RSS
Copyright SgDotNet 2004-2009
Powered by Community Server (Commercial Edition), by Telligent Systems