Перечислитель JScript и список свойств
Рассмотрим следующий фрагмент 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 ответа:
Оператор
JScript
for...in
несовместим с объектами WMI, поскольку они более сложны, чем собственные объекты JScript. Объекты WMI предоставляют свою коллекцию свойств через специальныйProperties_
таким образом, чтобы перечислить все доступные свойства объекта, необходимо перечислить эту коллекцию, как вы перечисляете результаты запроса для доступа к отдельным объектам WMI. Каждое свойство объекта представлено aSWbemProperty
объект, который имеет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 и несколько работ. Я запросил имя драйвера и комментарий, и оба имели текст или, по крайней мере, null.
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); }