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