JScript枚举器和属性列表

Ale*_*sky 6 wsh 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 + ")");
}

它在每一行打印一个打印机名称和括号中的"未定义"一词(因为对象中Status不存在p属性).问题是:我如何列出所有可用的属性p?通常的技术for (var i in p) {...}不起作用 - 似乎p对象中的属性不可枚举.

提前致谢.

Hel*_*len 10

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,此脚本还将显示DeviceID属性值,因为它是类的键属性Win32_Printer,因此也会检索它以便唯一标识类实例.


fla*_*let 6

如果您希望每次需要迭代需要迭代的集合对象时都不需要使用显式枚举器,那么您可以定义一个小辅助函数,如下所示:

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

然后对集合的迭代变得不那么笨拙了:

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);
    });
});
Run Code Online (Sandbox Code Playgroud)