System.Diagnostics.Process 類別提供強大的處理序管理功能。本文示範如何列舉所有處理序、取得詳細資訊(記憶體、CPU、執行緒、啟動時間等),並處理常見例外情況。
using System.Diagnostics;
using System.Windows.Forms;
public void RefreshProcessList(ListBox listBox)
{
listBox.Items.Clear();
// 取得所有處理序(依名稱排序較易閱讀)
var processes = Process.GetProcesses()
.OrderBy(p => p.ProcessName)
.ToArray();
foreach (var proc in processes)
{
listBox.Items.Add(proc.ProcessName);
}
if (listBox.Items.Count > 0)
listBox.SelectedIndex = 0;
}
public void ShowProcessDetails(string processName, Control parent)
{
try
{
// 依名稱取得處理序(可能有多個同名實例)
var processes = Process.GetProcessesByName(processName);
if (processes.Length == 0)
{
MessageBox.Show("找不到指定處理序", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 取得第一個實例(或讓使用者選擇)
var proc = processes[0];
// 更新 UI(範例使用 Label 控制項)
UpdateLabel(parent, "lblImageName", $"映像名稱:{proc.ProcessName}");
UpdateLabel(parent, "lblId", $"處理序 ID:{proc.Id}");
UpdateLabel(parent, "lblThreadCount", $"執行緒數:{proc.Threads.Count}");
UpdateLabel(parent, "lblCpuTime", $"CPU 時間:{proc.TotalProcessorTime}");
UpdateLabel(parent, "lblPriority", $"優先權類別:{proc.PriorityClass}");
UpdateLabel(parent, "lblStartTime", $"啟動時間:{proc.StartTime:yyyy-MM-dd HH:mm:ss}");
// 記憶體資訊(轉換為 KB/MB 易讀)
UpdateLabel(parent, "lblPrivateMemory", $"私有記憶體:{FormatBytes(proc.PrivateMemorySize64)}");
UpdateLabel(parent, "lblVirtualMemory", $"虛擬記憶體:{FormatBytes(proc.VirtualMemorySize64)}");
UpdateLabel(parent, "lblWorkingSet", $"工作集:{FormatBytes(proc.WorkingSet64)}");
UpdateLabel(parent, "lblPagedMemory", $"分頁記憶體:{FormatBytes(proc.PagedMemorySize64)}");
UpdateLabel(parent, "lblNonPagedMemory", $"非分頁記憶體:{FormatBytes(proc.NonpagedSystemMemorySize64)}");
// .NET 6+ 可用 PagedSystemMemorySize64 等 64 位元屬性
}
catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 5) // Access Denied
{
MessageBox.Show("存取被拒絕:權限不足,無法讀取該處理序資訊", "錯誤",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show($"發生錯誤:{ex.Message}", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void UpdateLabel(Control parent, string labelName, string text)
{
if (parent.Controls[labelName] is Label lbl)
lbl.Text = text;
}
private string FormatBytes(long bytes)
{
if (bytes >= 1024 * 1024 * 1024)
return $"{bytes / (1024.0 * 1024 * 1024):F2} GB";
if (bytes >= 1024 * 1024)
return $"{bytes / (1024.0 * 1024):F2} MB";
if (bytes >= 1024)
return $"{bytes / 1024.0:F2} KB";
return $"{bytes} Bytes";
}
public void ShowModulesAndThreads(int processId)
{
try
{
var proc = Process.GetProcessById(processId);
Console.WriteLine("=== 載入模組 ===");
foreach (ProcessModule mod in proc.Modules)
{
Console.WriteLine($"{mod.ModuleName,-40} {mod.FileVersionInfo?.FileVersion,-20} {mod.BaseAddress}");
}
Console.WriteLine("\n=== 執行緒詳細 ===");
foreach (ProcessThread thread in proc.Threads)
{
Console.WriteLine($"ID: {thread.Id,5} | 優先權: {thread.PriorityLevel,-10} | " +
$"狀態: {thread.ThreadState,-15} | CPU: {thread.TotalProcessorTime} | " +
$"啟動: {thread.StartTime:HH:mm:ss.fff}");
}
}
catch (Exception ex)
{
Console.WriteLine($"錯誤:{ex.Message}");
}
}
GetProcesses() 會建立快照,頻繁呼叫有效能成本,建議快取 1-5 秒GetProcessesByName 篩選再逐一取得細節PerformanceCounter 或 WMI/ETW 事件善用 Process 類別,能建立工作管理員、效能監控、診斷工具等實用應用。