2

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

我正在使用以下代码来获取 Windows 服务的路径....这里我使用EnumerationOptions来提高查询性能,现在为了使用它我必须使用ManagementScopewhich is "root\civm2",每个时间我必须使用“root'civm2”作为管理范围,

之前我managementObjectCollection.Count用来知道它是否包含任何项目,现在为了提高我正在使用的性能managementObjectEnumerator.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 ? 请指导。

4

2 回答 2

2

正如对另一个问题的回答建议您可以构建类的对象路径并直接使用 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...");
}
于 2012-05-09T17:52:19.717 回答
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...");
}
于 2014-12-11T19:23:35.187 回答