2012-05-09 34 views
2

我需要在我的service的構造函數中進行WMI調用。但是,當我啓動/重新啓動系統時,此調用需要大量時間。WMI調用性能

我正在使用下面的代碼來獲取Windows服務的路徑.... 在這裏我已經使用EnumerationOptions來提高查詢性能,現在爲了使用它,我必須使用ManagementScope這是「根\ 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? 請指導。

回答

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..."); 
} 
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..."); 
}