2017-01-25 166 views
0

在JScript.NET下面的代码片段:JScript.NET:枚举WMI集合

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文件说:

If successful, the method returns an SWbemObjectSet

此外,WSH的JScript可以枚举两InstancesOf收集和ExecQuery

回答

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对象的引用”从错误

“无法转换类型的COM对象 '系统.__ ComObject' 到接口类型“System.Collections.IEnumerabl E“。

看来,将集合转换为枚举器需要引用正在播放的对象。使用wbemFlagForwardOnly标志,没有引用通过,因此投射失败。

这就是我读这个的方法。把它看作是值得的。

我在研究中发现了一件有趣的事情:使用wscript/cscript与从jsc/csc执行exe的枚举器没有错误。

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