JScript Enumerator и список свойств - PullRequest
6 голосов
/ 10 июня 2009

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

var query = GetObject("winmgmts:").ExecQuery("SELECT Name 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 + ")");
}

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

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

Ответы [ 3 ]

10 голосов
/ 10 июня 2009

Оператор 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, поэтому он также извлекается для уникальной идентификации экземпляров класса.

6 голосов
/ 16 ноября 2010

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

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);
    });
});
1 голос
/ 10 июня 2009

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

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);
}
...