2012-01-28 140 views
1

我想檢索前臺進程(或特定進程)的cpu和ram使用情況。 檢索窗口的標題不是問題,該部分工作。但即使當活動窗口以70%cpu或更高的速度運行時,cpu顯示仍保持爲0%。C#從特定進程(性能計數器)獲取CPU和RAM

(int)pCPU.NextValue(); // < < < <總是返回0 ...

注意:我想用性能計數器來實現。我不想用Process變量來做這件事,因爲那個人可能會提出'不足的特權錯誤'。

[DllImport("user32.dll")] 
    static extern IntPtr GetForegroundWindow(); 

    [DllImport("user32.dll")] 
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId); 

    public void GetActiveCPUAndRam(out string windowTitle, out int CPUUsagePerc, out int RAMUsage) 
    { 
     IntPtr hwnd = GetForegroundWindow(); 
     uint pid; 
     GetWindowThreadProcessId(hwnd, out pid); 

     Process activeProc = Process.GetProcessById((int) pid); 

     #region Window Title 

     const int nChars = 256; 
     StringBuilder Buff = new StringBuilder(nChars); 
     if (GetWindowText(hwnd, Buff, nChars) > 0) 
      windowTitle = Buff.ToString(); 
     else 
     { 
      windowTitle = ""; 
      CPUUsagePerc = 0; 
      RAMUsage = 0; 
      return; 
     } 

     #endregion 

     #region RAM/CPU 
     PerformanceCounter pCPU = new PerformanceCounter("Process", "% Processor Time", activeProc.ProcessName, true); 
     pCPU.NextValue(); 
     CPUUsagePerc = (int)pCPU.NextValue(); // <<<<< problem here. 

     RAMUsage = 0; // TODO: 

     #endregion 
    } 



編輯: 我嘗試了新的解決方案: 但是當我運行是推動CPU使用率到100%(單核)一個CPU壓力測試程序。然後下面的解決方案顯示,該進程的CPU使用率是總CPU的300-400%...顯然有些東西仍然是錯誤的。


 private PerformanceCounter pCPU = null; 
     private IntPtr PreviousProcHwnd = IntPtr.Zero; 
     private CounterSample PreviousCPUCounterSample = CounterSample.Empty; 

     public void GetActiveCPUAndRam(out string windowTitle, out int CPUUsagePerc, out int RAMUsage) 
{ 
     ... 
     #region RAM/CPU 

     if (PreviousProcHwnd != hwnd) 
     { 
      PreviousProcHwnd = hwnd; 
      pCPU = new PerformanceCounter("Process", "% Processor Time", activeProc.ProcessName, 
                  true); 
      PreviousCPUCounterSample = CounterSample.Empty; 
     } 

     CounterSample sample1 = pCPU.NextSample(); 
     CPUUsagePerc = (int)CounterSample.Calculate(PreviousCPUCounterSample, sample1); 
     PreviousCPUCounterSample = sample1; 
     RAMUsage = 0; // TODO: 

     #endregion 
} 
+0

你見過http://openhardwaremonitor.org/嗎? – 2012-01-28 19:38:33

回答

0

不要直接使用的值,使用所計算的採樣,

CounterSample sample1 = pCPU.NextSample(); 
float value = CounterSample.Calculate(sample1); 

如果你的計數器是「速度」類型的樣品,那麼你將需要獲得兩個樣本,

CounterSample sample1 = counter.NextSample(); 
Thread.Sleep(1000); // wait some time 
CounterSample sample2 = counter.NextSample(); 
float value = CounterSample.Calculate(sample1, sample2); 
+0

第一個樣本不起作用。第二個示例給出了不同的cpu用法。我已經有另一個計數器來測量總cpu負載(這似乎是準確的),並且對於所有進程,顯示爲50%,而對於單個進程顯示爲60%...這不是很好。另外,如果沒有thread.sleep,不可能做到這一點,但只需要在同一個循環中完成,而不必將相同過程或以前的countersample存儲起來?我的應用程序依賴於幀率,不能像那樣睡覺。如果進程在睡眠期間關閉(),它也可能會崩潰。 – Napoleon 2012-01-28 20:24:35

+0

我對第二個示例做了一些更多的測試,其差異是由1秒延遲導致的課程..我感覺非常愚蠢..但是我說得對,當檢查過程終止於1時,這會使我的程序崩潰第二(這很可能)。 – Napoleon 2012-01-28 20:33:36

相關問題