I was inspecting some hardware properties and wrote the following
// Connect to WMI
Var locator As OLEObject = New OLEObject("WbemScripting.SWbemlocator", True)
Var wmiServiceParams() As Variant
// Set the WMI local params
wmiServiceParams.Add Nil // Param 0 is ignored
wmiServiceParams.Add "."
wmiServiceParams.Add "root\cimv2"
Var computerBoard As OLEObject = OLEObject(locator.Invoke("ConnectServer", wmiServiceParams)).InstancesOf("Win32_baseboard").ItemIndex(0)
MessageBox "Manufacturer: "+computerBoard.Manufacturer
MessageBox "Model: "+computerBoard.Model // This line raises a null access at my Dell, the work around is computerBoard.Value("Model")
computerBoard = Nil
locator = Nil
Exception err
MessageBox err.message
As you see, besides MS docs saying that “Model” should exist, seems that sometimes it may not.
I’m curious to list true ones.
So the question is, how do I, possessing the computerBoard OLEObject above, can build an Enumerator from it, and list its member names in Xojo?
1 Like
Oh boy I remember years ago stumbling onto how to do this and was told by Aaron Baldwin at the time that it was not possible
This was some years ago and sorry my memory is fuzzy at the moment
Well I just read the news that WMIC is deprecated so I’m very interested in how to get this information without shell.
1 Like
@Tim_Parnell
Yes WMIC is no longer supported in Windows OS going forward
But connecting to Cimv2 is not deprecated
1 Like
We Need a hand of @William_Yu here because I can’t advance after this point:
Error, line 16
There is more than one method with this name but this does not match any of the available signatures.
// Connect to WMI
Var locator As OLEObject = New OLEObject("WbemScripting.SWbemlocator", True)
Var wmiServiceParams() As Variant
// Set the WMI local params
wmiServiceParams.Add Nil // Param 0 is ignored
wmiServiceParams.Add "."
wmiServiceParams.Add "root\cimv2"
Var computerBoard As OLEObject = OLEObject(locator.Invoke("ConnectServer", wmiServiceParams)).InstancesOf("Win32_baseboard").ItemIndex(0)
Var props As OLEObject = computerBoard.SystemProperties__ // ISWbemPropertySet
Var propEnumerator As New COM.IEnumVariant(props._NewEnum) // Something wrong here, what?
Var prop As Variant
var fetched As UInt32
Call propEnumerator.Next_(1, prop, fetched ) // read one property for test
Break // Want to observe the property returned
propEnumerator = nil
props = nil
computerBoard = Nil
locator = Nil
exception err
msgbox err.message
Ok, MS Docs says that SWbemPropertySet._NewEnum returns an IEnumVariant, so an explicit cast “fix” the Xojo conflict but… I get a NULL instead of an Enumerator.
Var propEnumerator As New COM.IEnumVariant(COM.IEnumVariant(props._NewEnum)) // NOE!?
The properties are there, as we can see that props.Count returns a number
Xojo bug? Something else?
Just for information, the computerBoard.SystemProperties_ is stated in MS Docs as using ONE UNDERLINE but to make it work in Xojo I had to add TWO UNDERLINES .SystemProperties__ , because I saw Xojo “eating” one of the underlines in the debug.
Ok, I’ve made it work for my intents using another approach.
It’s just a proof of concept, probably needs enhancements when adapting for general use.
// This is just a proof of concept about reading WMI data
// Use it just as an example to you understand the concept and build something best suited for a proper use
// Connect to WMI
Var locator As OLEObject = New OLEObject("WbemScripting.SWbemlocator", True)
Var wmiServiceParams() As Variant
// Set the WMI local params
wmiServiceParams.Add Nil // Param 0 is ignored
wmiServiceParams.Add "."
wmiServiceParams.Add "root\cimv2"
Var computerBoard As OLEObject = OLEObject(locator.Invoke("ConnectServer", wmiServiceParams)).InstancesOf("Win32_baseboard").ItemIndex(0)
Var xmlString As String = computerBoard.GetText__(1) // Here we get all the properties data as XML
Var xmlComputerBoard As New XmlDocument(xmlString)
Var xmlWalker As XmlNode
Var data As New Dictionary // the data Dictionary will receive all the properties
// Let's build the dictionary from that WMI XML
xmlWalker = xmlComputerBoard.DocumentElement.FirstChild
Do Until xmlWalker = Nil
Var nameProperty As String = xmlWalker.GetAttribute("NAME")
Var valuesFound As Variant = Nil
If xmlWalker.ChildCount >= 1 Then
If xmlWalker.FirstChild.Name = "VALUE" Then
valuesFound = xmlWalker.FirstChild.FirstChild.Value
ElseIf xmlWalker.FirstChild.Name = "VALUE.ARRAY" Then
Var list() As Variant
Var xmlValue As XmlNode = xmlWalker.FirstChild.FirstChild
Do Until xmlValue = Nil
list.Add xmlValue.FirstChild.Value
xmlValue = xmlValue.NextSibling
Loop
valuesFound = list
End
End
data.Value(nameProperty) = valuesFound
xmlWalker = xmlWalker.NextSibling
Loop
Break // data dictionary contains all the data at this point
3 Likes