3

[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/WQLs 查询更快SELECT * FROM Win32_Printer WHERE Name = 'MyHP',但是如果有人对此进行了测试并且知道性能差异可以忽略不计,那么我对使用 WMI/WQL 感到满意(我不是作为一个程序员已经足够精明地测试这些东西了)。

如果有人有任何指示,我将不胜感激。谢谢...

4

1 回答 1

2

目前你有一个ManagementObjects 的集合,你需要一个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\"");

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

于 2013-05-18T00:39:08.977 回答