JScript.NET: Enumerating WMI collections

0

In JScript.NET the following snippet:

wmi.js
------
var wmi  = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2"),
    col =null, prc=null;
col=wmi.ExecQuery("SELECT * From Win32_Process", "WQL", 32);
//col=wmi.InstancesOf("Win32_Process");
var e = new Enumerator(col);
for (; !e.atEnd(); e.moveNext()){
  prc = e.item();
  print(prc.CommandLine);
}

compiles with:

%windir%\Microsoft.NET\Framework64\v4.0.30319\jsc.exe /platform:x64 wmi.js

and executes, but changing the WMI call with:

col=wmi.ExecQuery("SELECT * From Win32_Process", "WQL", 32);

compilation still works, while the execution gives the:

Unhandled Exception: System.InvalidCastException: 
Unable to cast COM object of type 'System.__ComObject' to interface type 'System.Collections.IEnumerable'. 
This operation failed because the QueryInterface call on the COM component for the interface with IID '{496B0ABE-CDEE-11D3-88E8-00902754C43A}' failed due to the following error: 
'No such interface supported (Exception from HRESULT: 0x80004002                        

I don't understand why, since for both InstancesOf and ExecQuery documentation says:

If successful, the method returns an SWbemObjectSet

Also, WSH JScript can enumerate both InstancesOf collection and ExecQuery.

collections
wmi
jscript
wmi-query
jscript.net
asked on Stack Overflow Jan 25, 2017 by antonio

1 Answer

1

First things first, remove the flag for wbemFlagForwardOnly and the ExecQuery returns an object that works as expected.

var wmi  = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2")
   , col =null, prc=null;

col=wmi.ExecQuery("SELECT * From Win32_Process");
//col=wmi.InstancesOf("Win32_Process");

var e = new Enumerator(col);
for (; !e.atEnd(); e.moveNext()){
  prc = e.item();
  print(prc.CommandLine);
}

For the explanation, here's a shot in the dark (I don't work with Jscript.NET every day nor am I an expert).

from https://msdn.microsoft.com/en-us/library/ms974547.aspx:

"A forward-only enumerator performs much faster than the default enumerator, because WMI doesn't maintain references to objects in the SWbemObjectSet"

from the error:

"Unable to cast COM object of type 'System.__ComObject' to interface type 'System.Collections.IEnumerable."

It seems that converting collection to enumerator requires a reference to the object being casted. With wbemFlagForwardOnly flag, there is no reference passed so cast fails.

That is how I read this. Take it for what it's worth.

An interesting thing I found when researching: there is no error with this enumerator using wscript/cscript versus executing exe from jsc/csc.

Also, it seems VBScript has no problem enumerating with these flags; check out the examples and compare - https://msdn.microsoft.com/en-us/library/ms525775(v=vs.90).aspx.

answered on Stack Overflow Mar 28, 2017 by HJ Cross • edited Mar 28, 2017 by HJ Cross

User contributions licensed under CC BY-SA 3.0