2014-02-09 64 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其他应用的潜力。