[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(作为程序员来测试这些东西,我还不够精明。)
如果有人有任何指示,我将不胜感激。感谢...
答案 0 :(得分:2)
目前您拥有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\"");
当然,这适用于本地系统上的打印机,但也可以相对轻松地为远程计算机构建路径。