2014-02-09 65 views
1

當前,從進程ID獲取實例名稱的解決方案來自以下代碼。 問題是,這需要大量的時間和CPU資源!從進程ID /對象獲取進程實例名稱(更快的方法)

也就是說,當您有一個運行至少100個進程的系統時,需要相當長的時間循環才能找到它。 (如1到2秒)當我期望找到多達30個這些進程時,最多需要30秒才能找到它們...

難道你不能簡單地從進程中獲取實例名稱目的?

private static string GetProcessInstanceName(int pid) 
{ 
    PerformanceCounterCategory cat = new PerformanceCounterCategory("Process"); 

    string[] instances = cat.GetInstanceNames(); 
    foreach (string instance in instances) 
    { 

    using (PerformanceCounter cnt = new PerformanceCounter("Process", 
      "ID Process", instance, true)) 
    { 
     int val = (int) cnt.RawValue; 
     if (val == pid) 
     { 
      return instance; 
     } 
    } 
    } 
    throw new Exception("Could not find performance counter " + 
     "instance name for current process. This is truly strange ..."); 
} 

回答

1

爲什麼不使用System.Diagnostics.Process.GetProcessById函數?

private static string GetProcessInstanceName(int pid) 
{ 
    string name = String.Empty; 
    Process proc = System.Diagnostics.Process.GetProcessById(pid); 
    if(proc != null) 
    { 
     name = proc.ProcessName; 
    } 
    return name; 
} 
+1

這樣做的問題是,如果存在多個相同nname的實例,例如:java#1 java#2,它不會返回正確的進程號..只是java。 – ultramoo

+0

@ user3289302你不能比'進程ID'更具體。如果你有它,它肯定會返回1(並且唯一)與該PID的過程。 –

+1

PerformanceCounter方法需要一個實例名稱,而不是一個PID ...就像這裏:new PerformanceCounter(「Process」,「%Processor Time」,instanceName);如果只有一個同名的實例在運行,但是當你有兩個相同的實例名時,你的方法不會像performanceCounter期待的那樣返回它。例如java#1 java# 2你會以其他方式知道嗎?或者有沒有辦法用pid提供PerformanceCounter? – ultramoo

0

這應該讓你所有的當前進程的

var allProcesses = System.Diagnostics.Process.GetProcesses(); 

,那麼你可以通過數組進行迭代,以找到特定ID的您正在尋找

0

一個非常快速和良好的工作解決方案是這一個:

public static string GetInstanceNameForProcessId(int processId) 
    { 
     var process = Process.GetProcessById(processId); 
     string processName = Path.GetFileNameWithoutExtension(process.ProcessName); 

     PerformanceCounterCategory cat = new PerformanceCounterCategory("Process"); 
     string[] instances = cat.GetInstanceNames() 
      .Where(inst => inst.StartsWith(processName)) 
      .ToArray(); 

     foreach (string instance in instances) 
     { 
      using (PerformanceCounter cnt = new PerformanceCounter("Process", 
       "ID Process", instance, true)) 
      { 
       int val = (int)cnt.RawValue; 
       if (val == processId) 
       { 
        return instance; 
       } 
      } 
     } 
     return null; 
    } 

Rick Strahl。我唯一的問題是一樣的一個在他的博客中評論:

有一點要提相關的窗口過程實例 的名字是他們動態改變時,流程出口之一。

例如,如果鉻#8出口,鉻#9將變得鉻#8和 鉻#10

將變得鉻#9。此時,獲取之前爲chrome#10創建的計數器 的值將引發異常。這是 真的很煩人,如果你想要監視 多個進程的多個實例,因爲它到達監視進程出口和 重新創建所有的計數器(真的很難看)。

一個辦法是改變的方式處理實例名稱是產生 (見http://support.microsoft.com/kb/281884)但這 影響使用性能監視器API其他應用的潛力。