JScript Enumerator и список свойств

Рассмотрим следующий фрагмент WSH:

var query = GetObject ("winmgmts:"). ExecQuery ("ВЫБРАТЬ имя из Win32_Printer", "WQL", 0);
var e = new Enumerator(query);
for (;!e.atEnd(); e.moveNext ()) { 
    var p = e.item();
    WScript.Echo(p.Name + " (" + p.Status + ")");
}

Он печатает в каждой строке имя принтера и слово "undefined" в скобках (потому что Status собственность не существует в p объект). Вопрос: как я могу перечислить все доступные свойства из p? Обычная техника с for (var i in p) {...} не работает - кажется, что свойства в p объект не перечисляем.

Заранее спасибо.

3 ответа

Решение

JScript-х for...in оператор не совместим с объектами WMI, потому что они более сложны, чем собственные объекты JScript. Объекты WMI выставляют свою коллекцию свойств через специальный Properties_ свойство, поэтому для получения списка всех доступных свойств объекта вам необходимо перечислить эту коллекцию так же, как вы перечислите результаты запроса для доступа к отдельным объектам WMI. Каждое свойство объекта представлено SWbemProperty объект, который имеет Name, Value и другие свойства, предоставляющие информацию о соответствующем свойстве объекта.

Этот пример должен помочь вам понять идею:

var query = GetObject("winmgmts:").ExecQuery("SELECT Name, Status FROM Win32_Printer");
var colPrinters = new Enumerator(query);

var oPrinter, colProps, p;

// Enumerate WMI objects
for ( ; !colPrinters.atEnd(); colPrinters.moveNext()) { 
    oPrinter = colPrinters.item();

    // Enumerate WMI object properties
    colProps = new Enumerator(oPrinter.Properties_);
    for ( ; !colProps.atEnd(); colProps.moveNext()) { 
        p = colProps.item();
        WScript.Echo(p.Name + ": " + p.Value);
    }
}

Обратите внимание, что этот скрипт также будет отображать DeviceID значение свойства, потому что это ключевое свойство Win32_Printer класс, поэтому он также извлекается для уникальной идентификации экземпляров класса.

Если вы хотите избежать необходимости использовать явный перечислитель каждый раз, когда вам нужно перебрать объект коллекции, в котором он нужен, вы можете определить небольшую вспомогательную функцию, например:

function forEach(collection, func) {
 for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
  func(e.item());
 }
}

Итерация по коллекциям становится менее неуклюжей:

var queryResult = GetObject("winmgmts:").ExecQuery("SELECT Name, Status FROM Win32_Printer");

// Enumerate WMI objects
forEach (queryResult, function (oPrinter) {

    // Enumerate WMI object properties
    forEach (oPrinter.Properties_, function (p) {
        WScript.Echo(p.Name + ": " + p.Value);
    });
});

Я думаю, что проблема в вашем запросе, вы спрашиваете только имя. Попробуйте запросить имя и статус:

var query = GetObject("winmgmts:").ExecQuery("SELECT Name, Status  FROM Win32_Printer", "WQL", 0);
var e = new Enumerator(query);
for ( ; !e.atEnd(); e.moveNext ()) { 
    var p = e.item();
    WScript.Echo(p.Name + " (" + p.Status + ")" );
}

Я получил еще несколько свойств от http://msdn.microsoft.com/en-us/library/aa394363(VS.85).aspx и несколько работ. Я запросил DriverName и Comment, и у обоих был текст или по крайней мере ноль.

var query = GetObject("winmgmts:").ExecQuery("SELECT Name, Status, DriverName, Comment  FROM Win32_Printer", "WQL", 0);
var e = new Enumerator(query);
for ( ; !e.atEnd(); e.moveNext ()) { 
    var p = e.item();
    WScript.Echo(p.Name + " (" + p.Status + ") " + p.DriverName + " " + p.Comment);
}
Другие вопросы по тегам