JScript.NET:枚举WMI集合

时间:2017-01-25 22:51:32

标签: collections wmi jscript wmi-query jscript.net

在JScript.NET中,以下代码段为:

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

编译:

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

并执行,但更改WMI来电:

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

编译仍然有效,而执行给出:

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                        

我不明白为什么,因为两者都是 InstancesOfExecQuery文档说:

  

如果成功,该方法返回SWbemObjectSet

此外,WSH JScript可以枚举InstancesOf集合和ExecQuery

1 个答案:

答案 0 :(得分:1)

首先,删除wbemFlagForwardOnly的标志,ExecQuery返回一个按预期工作的对象。

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

对于解释,这是一个黑暗的镜头(我不是每天都使用Jscript.NET,也不是专家)。

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

“仅向前的枚举器的执行速度比默认的枚举器快得多,因为WMI不维护对SWbemObjectSet中对象的引用”

来自错误的

“无法将'System .__ ComObject'类型的COM对象强制转换为接口类型'System.Collections.IEnumerable。”

似乎将集合转换为枚举器需要引用正在转换的对象。使用wbemFlagForwardOnly标志,没有传递引用,因此强制转换失败。

这就是我读这个的方式。把它拿走它的价值。

我在研究时发现了一个有趣的事情:这个枚举器使用wscript / cscript而不是从jsc / csc执行exe时没有错误。

此外,似乎VBScript枚举这些标志没有问题;查看示例并进行比较 - https://msdn.microsoft.com/en-us/library/ms525775(v=vs.90).aspx