2017-01-25 348 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