2009-06-09 109 views
6

列表考虑以下WSH片段:JScript中枚举和属性

 
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对象中的属性不可枚举。

在此先感谢。

回答

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

注意,该脚本也将显示DeviceID属性值,因为它是Win32_Printer类的关键属性,所以它也是为了获取唯一识别类实例。

1

我认为问题出在您的查询中,您只需要提供姓名。试着问两个名称和状态:

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,并且都有文本或至少为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); 
} 
+0

感谢您的回答,但我的问题是不是在查询:)不管SELECT语句中,对对象的属性是不可发现(与“为”)和这是荒谬的:( – 2009-06-10 01:06:23

+0

“是的,我试着从F的SELECT * ROM Win32_Printer“,然后为(我在p上)和打印我和p.i而没有任何东西。但是我发布的链接确实有你想要的所有属性,所以也许只是把它们放在一个数组中以便让它们出来。所有我测试过的都在那里。 http://msdn.microsoft.com/en-us/library/aa394363(VS.85).aspx – artlung 2009-06-10 01:47:46

6

如果你想避免需要使用显式枚举每次你需要遍历需要一个集合对象时,你可以定义一个小助手功能如下:

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