0

在 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.

4

1 回答 1

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

于 2017-03-28T04:29:07.687 回答