WMI呼叫性能

时间:2012-05-09 17:04:30

标签: c# wmi

我需要在我的服务的构造函数中进行WMI调用。但是,当我启动/重新启动系统时,此调用会花费大量时间。

我使用以下代码获取Windows服务的路径.... 在这里我使用EnumerationOptions来提高查询性能,现在为了使用它,我必须使用ManagementScope,它是“root \ civm2”,每次我都要使用“root”civm2 “作为管理范围,

早些时候我正在使用manageObjectCollection.Count来知道它是否包含任何项目,现在为了提高我使用manageObjectEnumerator.MoveNext的性能,它会有所帮助,我已经评论了与计数相关的代码。

有没有更好的方法来改善相同代码的性能......

EnumerationOptions options = new EnumerationOptions();
//   options.Rewindable = false; **// I HAVE TO COMMENT OUT THIS IN ORDER TO GET THE RESULTS....**
options.ReturnImmediately = true;

string query = string.Format("SELECT PathName FROM Win32_Service WHERE Name = '{0}'", "MyService");


ManagementScope ms12 = new ManagementScope(@"root\cimv2");
ms12.Connect();


using (var managementObjectSearcher = new ManagementObjectSearcher(query))
{
    managementObjectSearcher.Scope = ms12;
    managementObjectSearcher.Options = options;

    var managementObjectCollection = managementObjectSearcher.Get();

    //if (managementObjectCollection.Count > 0)
    //{
        var managementObjectEnumerator = managementObjectCollection.GetEnumerator();

        if (managementObjectEnumerator.MoveNext())
        {
            var invalidChars = new Regex(string.Format(CultureInfo.InvariantCulture, "[{0}]", Regex.Escape(new string(Path.GetInvalidPathChars()))));
            var path = invalidChars.Replace(managementObjectEnumerator.Current.GetPropertyValue("PathName").ToString(), string.Empty);
                Console.WriteLine(path);
        }
    //}
        else
        {
            Console.WriteLine("Else part...");
        }
}

我是否以正确的方式使用范围和EnumerationOption? 请指导。

2 个答案:

答案 0 :(得分:2)

由于你的另一个question的答案建议你可以构建类的对象路径并直接使用ManagementObject来提高性能,现在如果要检查ManagementObject是否返回一个实例,你可以使用私有财产IsBound

string ServicePath = string.Format("Win32_Service.Name=\"{0}\"", "MyService");
var WMiObject = new ManagementObject(ServicePath);
PropertyInfo PInfo = typeof(ManagementObject).GetProperty("IsBound", BindingFlags.NonPublic | BindingFlags.Instance);
if ((bool)PInfo.GetValue(WMiObject, null))
{
    string PathName = (string)WMiObject.GetPropertyValue("PathName");
    var invalidChars = new Regex(string.Format(CultureInfo.InvariantCulture, "[{0}]", Regex.Escape(new string(Path.GetInvalidPathChars()))));
    var path = invalidChars.Replace(PathName, string.Empty);
    Console.WriteLine(path);
}
else
{
    Console.WriteLine("Else part...");
}

答案 1 :(得分:0)

似乎在最新版本的.NET框架中,绑定会尽可能晚地发生。当我测试特定共享文件夹的存在时,至少就是这种情况。

以下是@RRUZ解决方案的更新,该解决方案使用try-catch而不是反映IsBound内部属性。

var servicePath = string.Format("Win32_Service.Name=\"{0}\"", "MyService");
string pathName = null;
try
{
    var wmiObject = new ManagementObject(servicePath);
    pathName = (string)wmiObject.GetPropertyValue("PathName");
}
catch {}

if (pathName != null)
{
    var invalidChars = new Regex(string.Format(CultureInfo.InvariantCulture, "[{0}]", Regex.Escape(new string(Path.GetInvalidPathChars()))));
    var path = invalidChars.Replace(pathName, string.Empty);
    Console.WriteLine(path);
}
else
{
    Console.WriteLine("Else part...");
}