如何使用LINQ查询ManagementObjectCollection,然后在PropertyData中循环返回Man

本文关键字:PropertyData 循环 返回 Man 然后 LINQ 何使用 查询 ManagementObjectCollection | 更新日期: 2023-09-27 18:14:16

[C#.NET Windows窗体WMI]

我是C#的新手,但我有VBScript的经验,我正在尝试将我写的脚本转换为C#。我不只是使用转换器,而是重写代码并尝试优化它,以帮助我学习。

一点背景

在我最初的VBScript中,我使用以下代码连接到远程服务器一次:

Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root'cimv2", strUserName, strPassword)
objSWbemServices.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate

然后我循环浏览我正在寻找的打印机列表,并调用一个具有以下代码的函数:

Set colPorts = objConnection.ExecQuery("SELECT * FROM Win32_Printer WHERE Name = '" & strPrinter & "'")  
If colPorts.Count = 0 Then
    Set objPort = objConnection.Get("Win32_TCPIPPrinterPort").SpawnInstance_

派生实例后,我将想要的属性添加到Dictionary对象中,该对象具有任意字符串值,我正在搜索的打印机作为关键字,属性作为值。因此,当我断开与服务器的连接时,我已经有了一个字典对象,其中包含了我需要在该服务器上使用的所有打印机(我也对端口做同样的事情(。

使用C#,我看起来不需要使用字典,因为我可以使用ManagementObjectSearcher返回ManagementObjectCollection。然后,如果我正确理解了这一点,我应该能够从单个ManagementObject或深入到PropertyData中获得我想要的特定打印机所需的属性。和我一起走了这么远?

问题/机会

因为我要返回整个集合,所以我认为使用LINQ查找需要使用的特定打印机会更高效,而不是循环整个集合。然后,一旦我从LINQ获得了ManagementObject,我就可以将PropertyData分配给一个变量以供以后使用(假设这是可能的(,或者循环使用PropertyData来查看内容(主要用于调试(。

我用以下代码尝试了后者,但没有任何运气:

var printer = from ManagementObject x in mocPrinters
                      where x.Properties["Name"].Value.ToString() == "MyHP"
                      select x;
foreach (PropertyData p in printer)
{
    MessageBox.Show(string.format("{0}: {1}", p.Name, p.Value);
}

上面的代码没有起作用,因为我假设我的打印机不是PropertyData类型。

其他有用信息

我原以为在返回整个集合后使用LINQ进行查询会比使用WMI/WQL的SELECT * FROM Win32_Printer WHERE Name = 'MyHP'进行查询更快,但如果有人已经测试过这一点,并且知道性能差异可以忽略不计,那么我就满足于使用WMI/WQL(作为一名程序员,我还不够精明,无法测试这些东西(。

如果有人有什么建议,我将不胜感激。谢谢。。。

如何使用LINQ查询ManagementObjectCollection,然后在PropertyData中循环返回Man

当前您有一个ManagementObject的集合,并且需要一个PropertyData的集合。

我想你的意思是这样的:

var printers = from ManagementObject x in mocPrinters
                      where x.Properties["Name"].Value.ToString() == "MyHP"
                      select x;
foreach (PropertyData p in printers.First().Properties)
{
    MessageBox.Show(string.format("{0}: {1}", p.Name, p.Value);
}

我将WMI用于其他任务的经验是,当您在查询中包含筛选时,执行速度会更快。LINQ与其说是计算效率,不如说是表达能力。

访问属性的最快方法是直接构建WMI路径。在打印机的情况下,路径中使用的DeviceID似乎就是名称。因此,您可以使用获取对象

var printer = new ManagementObject("Win32Printer.DeviceID='"MyHP'"");

当然,这是针对本地系统上的打印机的,但为远程机器构建路径也相对容易。