2017-01-25 11 views
0

В JScript.NET следующий фрагмент:JScript.NET: коллекции Enumerating 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       

Я не понимаю, почему, так как для InstancesOf и ExecQuery документация говорит:

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 е «.

Кажется, что для преобразования коллекции в счетчик требуется ссылка на подлежащий объект. С флагом wbemFlagForwardOnly не передается ссылка, поэтому сбой выполняется.

Вот как я прочитал это. Возьмите его за то, что он стоит.

Интересная вещь, которую я обнаружил при исследовании: нет ошибки с этим перечислителем, используя wscript/cscript и исполняющий exe из jsc/csc.

Кроме того, похоже, что VBScript не имеет проблем с перечислением этих флагов; проверьте примеры и сравните - https://msdn.microsoft.com/en-us/library/ms525775(v=vs.90).aspx.