开源 C# 快速开发(十二)进程监控
文章的目的为了记录使用C# 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
开源 C# 快速开发(一)基础知识
开源 C# 快速开发(二)基础控件
开源 C# 快速开发(三)复杂控件
开源 C# 快速开发(四)自定义控件--波形图
开源 C# 快速开发(五)自定义控件--仪表盘
开源 C# 快速开发(六)自定义控件--圆环
开源 C# 快速开发(七)通讯--串口
开源 C# 快速开发(八)通讯--Tcp服务器端
开源 C# 快速开发(九)通讯--Tcp客户端
开源 C# 快速开发(十)通讯--http客户端
开源 C# 快速开发(十一)线程
开源 C# 快速开发(十二)进程监控
推荐链接:
开源 C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客
开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客
开源 C# .net mvc 开发(三)WEB内外网访问-CSDN博客
开源 C# .net mvc 开发(四)工程结构、页面提交以及显示-CSDN博客
开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客
开源 C# .net mvc 开发(六)发送邮件、定时以及CMD编程-CSDN博客
开源 C# .net mvc 开发(七)动态图片、动态表格和json数据生成-CSDN博客
开源 C# .net mvc 开发(八)IIS Express轻量化Web服务器的配置和使用-CSDN博客
开源 C# .net mvc 开发(九)websocket--服务器与客户端的实时通信-CSDN博客
本章节主要内容是:展示进程管理功能,具有良好的错误处理和用户交互设计。
什么是进程?
进程是正在执行的程序的实例,它包含了程序执行所需的所有资源:
// 进程包含的主要资源
- 代码段(执行的指令)
- 数据段(变量、数据结构)
- 堆栈(函数调用、局部变量)
- 文件句柄、网络连接
- 安全上下文(用户权限)
- 执行状态(运行、等待、就绪等)
进程 (Process) 线程 (Thread) -------------- ------------- ❖ 资源分配的基本单位 ❖ CPU调度的基本单位 ❖ 拥有独立的内存空间 ❖ 共享进程的内存空间 ❖ 创建和销毁开销大 ❖ 创建和销毁开销小 ❖ 进程间通信复杂 ❖ 线程间通信简单 ❖ 一个进程包含多个线程 ❖ 线程是进程内的执行单元
进程的用途
启动外部应用程序
进程监控和管理
进程间通信(IPC)
系统资源监控
目录:
1.源码分析
2.所有源码
3.效果演示
一、源码分析
1. MainForm.cs - 主窗体类
构造函数
public MainForm()
{InitializeComponent();InitializeCustomComponents();
}
功能分析:
调用两个初始化方法完成窗体的构建
这是窗体的标准初始化模式
InitializeCustomComponents() 函数
private void InitializeCustomComponents()
{processMonitor = new ProcessMonitorControl{Location = new Point(10, 10),Size = new Size(780, 450),Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right};this.Controls.Add(processMonitor);
}
功能分析:
创建ProcessMonitorControl用户控件实例
设置控件位置和大小
设置锚点属性,使控件能随窗体大小自动调整
将控件添加到窗体控件集合中
Form1_Load() 函数
private void Form1_Load(object sender, EventArgs e)
{this.Text = "高级进程监控器 - .NET 4.0";this.Size = new Size(800, 500);this.StartPosition = FormStartPosition.CenterScreen;
}
功能分析:
设置窗体标题
设置窗体初始大小
设置窗体启动位置为屏幕中央
2. ProcessMonitorControl.cs - 进程监控用户控件
构造函数
public ProcessMonitorControl()
{InitializeComponent();processMonitor = new AdvancedProcessMonitor();InitializeTimer();RefreshProcessList();
}
功能分析:
初始化用户界面组件
创建高级进程监控器实例
启动定时器用于自动刷新
首次加载进程列表
InitializeComponent() 函数
UI构建分析:
主布局:使用TableLayoutPanel创建2列4行的网格布局
标题区域:跨列显示应用程序标题
进程列表:使用ListView显示进程信息,包含5个列
详情面板:右侧显示选中进程的详细信息
输出面板:底部显示命令执行输出
按钮面板:包含5个功能按钮的流式布局
事件处理函数
processListView_SelectedIndexChanged()
private void processListView_SelectedIndexChanged(object sender, EventArgs e)
{if (processListView.SelectedItems.Count > 0){int pid = int.Parse(processListView.SelectedItems[0].Text);UpdateProcessDetails(pid);}
}
功能分析:
监听列表选择变化事件
从选中项获取进程ID
调用详情更新函数
按钮点击事件处理函数
private void refreshBtn_Click(object sender, EventArgs e) => RefreshProcessList();
private void startBtn_Click(object sender, EventArgs e) => StartProcess_Click(sender, e);
private void killBtn_Click(object sender, EventArgs e) => KillProcess_Click(sender, e);
private void detailsBtn_Click(object sender, EventArgs e) => ShowDetails_Click(sender, e);
private void runCmdBtn_Click(object sender, EventArgs e) => RunCommand_Click(sender, e);
功能分析:
将按钮点击转发到对应的功能函数
提供统一的事件处理入口
核心功能函数
InitializeTimer() 函数
private void InitializeTimer()
{refreshTimer = new Timer();refreshTimer.Interval = 5000;refreshTimer.Tick += new EventHandler(refreshTimer_Tick);refreshTimer.Start();
}
功能分析:
创建定时器实例
设置5秒刷新间隔
绑定定时器滴答事件
启动定时器
refreshTimer_Tick() 函数
private void refreshTimer_Tick(object sender, EventArgs e)
{RefreshProcessList();
}
功能分析:
定时器事件处理函数
定期刷新进程列表
RefreshProcessList() 函数
private void RefreshProcessList()
{try{processListView.BeginUpdate();processListView.Items.Clear();Process[] processes = Process.GetProcesses();foreach (Process process in processes){try{ListViewItem item = new ListViewItem(process.Id.ToString());item.SubItems.Add(process.ProcessName);item.SubItems.Add((process.WorkingSet64 / 1024 / 1024).ToString());item.SubItems.Add(process.TotalProcessorTime.ToString(@"hh\:mm\:ss"));// 安全获取启动时间try { item.SubItems.Add(process.StartTime.ToString("yyyy-MM-dd HH:mm:ss")); }catch { item.SubItems.Add("N/A"); }processListView.Items.Add(item);}catch (Exception ex) { Debug.WriteLine("无法访问进程 " + process.Id + ": " + ex.Message); }}}catch (Exception ex) { MessageBox.Show("刷新进程列表失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); }finally { processListView.EndUpdate(); }
}
功能分析:
BeginUpdate()/EndUpdate():批量更新期间禁止重绘,提高性能
Process.GetProcesses():获取系统所有进程
遍历每个进程,安全地获取信息
内存计算:WorkingSet64 / 1024 / 1024 将字节转换为MB
时间格式化:@"hh\:mm\:ss" 显示时分秒
异常处理:对每个进程单独处理,避免一个进程出错影响整个列表
UpdateProcessDetails() 函数
private void UpdateProcessDetails(int processId)
{try{string details = processMonitor.GetProcessDetails(processId);detailsTextBox.Text = details;}catch (Exception ex){detailsTextBox.Text = "获取进程详情失败: " + ex.Message;}
}
功能分析:
调用高级监控器获取详细信息
在文本框中显示结果
异常处理确保UI稳定性
StartProcess_Click() 函数
private void StartProcess_Click(object sender, EventArgs e)
{using (OpenFileDialog dialog = new OpenFileDialog()){dialog.Filter = "可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*";dialog.Title = "选择要启动的应用程序";if (dialog.ShowDialog() == DialogResult.OK){try{Process.Start(dialog.FileName);RefreshProcessList();}catch (Exception ex){MessageBox.Show("启动进程失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);}}}
}
功能分析:
使用OpenFileDialog让用户选择可执行文件
设置文件过滤器
启动选中的进程
刷新列表显示新进程KillProcess_Click() 函数
private void KillProcess_Click(object sender, EventArgs e)
{if (processListView.SelectedItems.Count == 0){MessageBox.Show("请先选择一个进程", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);return;}int pid = int.Parse(processListView.SelectedItems[0].Text);string processName = processListView.SelectedItems[0].SubItems[1].Text;DialogResult result = MessageBox.Show("确定要终止进程 " + processName + " (PID: " + pid + ") 吗?", "确认终止", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);if (result == DialogResult.Yes){try{processMonitor.KillProcess(pid);RefreshProcessList();detailsTextBox.Clear();}catch (Exception ex){MessageBox.Show("终止进程失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);}}
}
功能分析:
验证是否有选中的进程
显示确认对话框防止误操作
调用监控器的终止功能
清理详情显示
ShowDetails_Click() 函数
private void ShowDetails_Click(object sender, EventArgs e)
{if (processListView.SelectedItems.Count > 0){int pid = int.Parse(processListView.SelectedItems[0].Text);UpdateProcessDetails(pid);}
}
功能分析:
手动触发详情显示
与选择变化事件功能相同,提供额外入口
RunCommand_Click() 函数
private void RunCommand_Click(object sender, EventArgs e)
{string command = ShowInputDialog("请输入要执行的命令 (例如: ipconfig /all):", "运行命令", "ipconfig");if (!string.IsNullOrEmpty(command)){outputTextBox.Clear();processMonitor.StartProcessWithWait(command, outputTextBox);}
}
功能分析:
显示自定义输入对话框获取命令
清空输出区域
执行命令并实时显示输出
ShowInputDialog() 函数
private string ShowInputDialog(string text, string caption, string defaultValue)
{Form prompt = new Form();prompt.Width = 400;prompt.Height = 150;// ... 对话框构建代码
}
功能分析:
动态创建输入对话框窗体
包含标签、文本框、确定取消按钮
返回用户输入的命令字符串
3. AdvancedProcessMonitor.cs - 核心监控功能类
StartProcessWithWait() 函数
public void StartProcessWithWait(string command, TextBox outputTextBox = null)
{try{ProcessStartInfo startInfo = new ProcessStartInfo();startInfo.FileName = "cmd.exe";startInfo.Arguments = "/c " + command;startInfo.UseShellExecute = false;startInfo.RedirectStandardOutput = true;startInfo.RedirectStandardError = true;startInfo.CreateNoWindow = true;startInfo.StandardOutputEncoding = Encoding.GetEncoding("GBK");startInfo.StandardErrorEncoding = Encoding.GetEncoding("GBK");// ... 进程执行和输出处理}catch (Exception ex) { /* 异常处理 */ }
}
功能分析:
使用cmd.exe /c执行命令,支持所有命令行指令
重定向标准输出和错误输出
设置中文编码支持
异步读取输出流
实时更新UI显示
AppendToTextBox() 函数
private void AppendToTextBox(TextBox textBox, string text)
{if (textBox != null && !textBox.IsDisposed){if (textBox.InvokeRequired){textBox.Invoke(new Action<TextBox, string>(AppendToTextBox), new object[] { textBox, text });}else{textBox.AppendText(text);textBox.ScrollToCaret();}}
}
功能分析:
线程安全的文本框更新
InvokeRequired检查是否需要在UI线程执行
使用Invoke进行跨线程调用
ScrollToCaret()自动滚动到最新内容
GetProcessDetails() 函数
public string GetProcessDetails(int processId)
{StringBuilder sb = new StringBuilder();try{Process process = Process.GetProcessById(processId);sb.AppendLine("=== 进程详细信息 ===");sb.AppendLine("进程名称: " + process.ProcessName);sb.AppendLine("进程ID: " + process.Id);// ... 添加各种进程属性}catch (Exception ex) { sb.AppendLine("获取进程信息失败: " + ex.Message); }return sb.ToString();
}
功能分析:
使用StringBuilder高效构建字符串
安全访问可能抛出异常的属性(如MainModule、StartTime)
返回格式化的详细信息字符串
KillProcess() 函数
public void KillProcess(int processId)
{try{Process process = Process.GetProcessById(processId);process.Kill();process.WaitForExit(5000);}catch (ArgumentException) { throw new Exception("未找到PID为 " + processId + " 的进程"); }catch (InvalidOperationException) { throw new Exception("进程已经退出"); }catch (Win32Exception ex) { throw new Exception("权限不足或系统错误: " + ex.Message); }
}
功能分析:
Process.GetProcessById()根据ID获取进程实例
process.Kill()强制终止进程
WaitForExit(5000)等待进程退出,超时5秒
详细的异常分类处理
StartProcess() 函数
public void StartProcess(string fileName, string arguments = "")
{try{ProcessStartInfo startInfo = new ProcessStartInfo();startInfo.FileName = fileName;startInfo.Arguments = arguments;startInfo.UseShellExecute = true;Process.Start(startInfo);}catch (Exception ex) { throw new Exception("启动进程失败: " + ex.Message); }
}
功能分析:
使用UseShellExecute = true通过系统shell启动进程
支持带参数启动
简单的异常包装
二、所有源码
AdvancedProcessMonitor.cs源码
using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;namespace ProcessMonitorApp
{public class AdvancedProcessMonitor{/// <summary>/// 启动进程并等待完成,实时输出到文本框/// </summary>public void StartProcessWithWait(string command, TextBox outputTextBox = null){try{ProcessStartInfo startInfo = new ProcessStartInfo();startInfo.FileName = "cmd.exe";startInfo.Arguments = "/c " + command;startInfo.UseShellExecute = false;startInfo.RedirectStandardOutput = true;startInfo.RedirectStandardError = true;startInfo.CreateNoWindow = true;startInfo.StandardOutputEncoding = Encoding.GetEncoding("GBK"); // 支持中文startInfo.StandardErrorEncoding = Encoding.GetEncoding("GBK");using (Process process = new Process()){process.StartInfo = startInfo;// 异步读取输出process.OutputDataReceived += (sender, e) =>{if (!string.IsNullOrEmpty(e.Data)){AppendToTextBox(outputTextBox, e.Data + "\r\n");}};process.ErrorDataReceived += (sender, e) =>{if (!string.IsNullOrEmpty(e.Data)){AppendToTextBox(outputTextBox, "[错误] " + e.Data + "\r\n");}};AppendToTextBox(outputTextBox, "执行命令: " + command + "\r\n");AppendToTextBox(outputTextBox, new string('=', 50) + "\r\n");process.Start();process.BeginOutputReadLine();process.BeginErrorReadLine();process.WaitForExit();AppendToTextBox(outputTextBox, new string('=', 50) + "\r\n");AppendToTextBox(outputTextBox, "命令执行完成,退出代码: " + process.ExitCode + "\r\n");}}catch (Win32Exception ex){AppendToTextBox(outputTextBox, "系统错误: " + ex.Message + "\r\n");}catch (Exception ex){AppendToTextBox(outputTextBox, "执行失败: " + ex.Message + "\r\n");}}private void AppendToTextBox(TextBox textBox, string text){if (textBox != null && !textBox.IsDisposed){if (textBox.InvokeRequired){textBox.Invoke(new Action<TextBox, string>(AppendToTextBox), new object[] { textBox, text });}else{textBox.AppendText(text);textBox.ScrollToCaret();}}}/// <summary>/// 获取进程详细信息/// </summary>public string GetProcessDetails(int processId){StringBuilder sb = new StringBuilder();try{Process process = Process.GetProcessById(processId);sb.AppendLine("=== 进程详细信息 ===");sb.AppendLine("进程名称: " + process.ProcessName);sb.AppendLine("进程ID: " + process.Id);sb.AppendLine("会话ID: " + process.SessionId);sb.AppendLine("基础优先级: " + process.BasePriority);// .NET 4.0 中需要安全地访问 MainModuletry{sb.AppendLine("主模块: " + process.MainModule.ModuleName);}catch{sb.AppendLine("主模块: N/A");}sb.AppendLine("主窗口标题: " + process.MainWindowTitle);sb.AppendLine("响应状态: " + process.Responding);// .NET 4.0 中需要安全地访问启动时间try{sb.AppendLine("启动时间: " + process.StartTime.ToString("yyyy-MM-dd HH:mm:ss"));}catch{sb.AppendLine("启动时间: N/A");}sb.AppendLine("总处理器时间: " + process.TotalProcessorTime.ToString(@"hh\:mm\:ss"));sb.AppendLine("用户处理器时间: " + process.UserProcessorTime.ToString(@"hh\:mm\:ss"));sb.AppendLine("特权处理器时间: " + process.PrivilegedProcessorTime.ToString(@"hh\:mm\:ss"));sb.AppendLine("物理内存使用: " + (process.WorkingSet64 / 1024 / 1024) + " MB");sb.AppendLine("分页内存大小: " + (process.PagedMemorySize64 / 1024 / 1024) + " MB");sb.AppendLine("虚拟内存大小: " + (process.VirtualMemorySize64 / 1024 / 1024) + " MB");sb.AppendLine("私有内存大小: " + (process.PrivateMemorySize64 / 1024 / 1024) + " MB");sb.AppendLine("句柄数量: " + process.HandleCount);sb.AppendLine("线程数量: " + process.Threads.Count);}catch (Exception ex){sb.AppendLine("获取进程信息失败: " + ex.Message);}return sb.ToString();}/// <summary>/// 终止指定进程/// </summary>public void KillProcess(int processId){try{Process process = Process.GetProcessById(processId);process.Kill();process.WaitForExit(5000); // 等待5秒}catch (ArgumentException){throw new Exception("未找到PID为 " + processId + " 的进程");}catch (InvalidOperationException){throw new Exception("进程已经退出");}catch (Win32Exception ex){throw new Exception("权限不足或系统错误: " + ex.Message);}}/// <summary>/// 启动独立进程/// </summary>public void StartProcess(string fileName, string arguments = ""){try{ProcessStartInfo startInfo = new ProcessStartInfo();startInfo.FileName = fileName;startInfo.Arguments = arguments;startInfo.UseShellExecute = true;Process.Start(startInfo);}catch (Exception ex){throw new Exception("启动进程失败: " + ex.Message);}}}
}
ProcessMonitorControl.cs源码
using System;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace ProcessMonitorApp
{public partial class ProcessMonitorControl : UserControl{private Timer refreshTimer;private AdvancedProcessMonitor processMonitor;private ListView processListView;private TextBox detailsTextBox;private TextBox outputTextBox;public ProcessMonitorControl(){InitializeComponent();processMonitor = new AdvancedProcessMonitor();InitializeTimer();RefreshProcessList();}private void InitializeComponent(){this.SuspendLayout();// 主表格布局TableLayoutPanel mainLayout = new TableLayoutPanel();mainLayout.Dock = DockStyle.Fill;mainLayout.ColumnCount = 2;mainLayout.RowCount = 4;mainLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 70F));mainLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 30F));mainLayout.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));mainLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 70F));mainLayout.RowStyles.Add(new RowStyle(SizeType.Absolute, 100F));mainLayout.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));// 标题标签Label titleLabel = new Label();titleLabel.Text = "高级进程监控器 (.NET 4.0)";titleLabel.Dock = DockStyle.Fill;titleLabel.TextAlign = ContentAlignment.MiddleCenter;titleLabel.Font = new Font("Microsoft YaHei", 12F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(134)));titleLabel.ForeColor = Color.DarkBlue;mainLayout.Controls.Add(titleLabel, 0, 0);mainLayout.SetColumnSpan(titleLabel, 2);// 进程列表processListView = new ListView();processListView.Dock = DockStyle.Fill;processListView.View = View.Details;processListView.FullRowSelect = true;processListView.GridLines = true;processListView.Columns.Add("PID", 80, HorizontalAlignment.Left);processListView.Columns.Add("进程名称", 150, HorizontalAlignment.Left);processListView.Columns.Add("内存(MB)", 100, HorizontalAlignment.Right);processListView.Columns.Add("CPU时间", 120, HorizontalAlignment.Left);processListView.Columns.Add("启动时间", 150, HorizontalAlignment.Left);processListView.SelectedIndexChanged += new EventHandler(processListView_SelectedIndexChanged);mainLayout.Controls.Add(processListView, 0, 1);// 进程详情面板Panel detailsPanel = new Panel();detailsPanel.Dock = DockStyle.Fill;detailsPanel.BorderStyle = BorderStyle.FixedSingle;detailsTextBox = new TextBox();detailsTextBox.Dock = DockStyle.Fill;detailsTextBox.Multiline = true;detailsTextBox.ScrollBars = ScrollBars.Vertical;detailsTextBox.ReadOnly = true;detailsTextBox.Font = new Font("Consolas", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));detailsPanel.Controls.Add(detailsTextBox);mainLayout.Controls.Add(detailsPanel, 1, 1);// 命令输出面板Panel outputPanel = new Panel();outputPanel.Dock = DockStyle.Fill;outputPanel.BorderStyle = BorderStyle.FixedSingle;outputTextBox = new TextBox();outputTextBox.Dock = DockStyle.Fill;outputTextBox.Multiline = true;outputTextBox.ScrollBars = ScrollBars.Vertical;outputTextBox.ReadOnly = true;outputTextBox.Font = new Font("Consolas", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));outputPanel.Controls.Add(outputTextBox);mainLayout.Controls.Add(outputPanel, 0, 2);mainLayout.SetColumnSpan(outputPanel, 2);// 按钮面板FlowLayoutPanel buttonPanel = new FlowLayoutPanel();buttonPanel.Dock = DockStyle.Fill;buttonPanel.FlowDirection = FlowDirection.LeftToRight;Button refreshBtn = new Button();refreshBtn.Text = "刷新列表";refreshBtn.Size = new Size(80, 30);refreshBtn.Click += new EventHandler(refreshBtn_Click);Button startBtn = new Button();startBtn.Text = "启动进程";startBtn.Size = new Size(80, 30);startBtn.Click += new EventHandler(startBtn_Click);Button killBtn = new Button();killBtn.Text = "终止进程";killBtn.Size = new Size(80, 30);killBtn.Click += new EventHandler(killBtn_Click);Button detailsBtn = new Button();detailsBtn.Text = "详细信息";detailsBtn.Size = new Size(80, 30);detailsBtn.Click += new EventHandler(detailsBtn_Click);Button runCmdBtn = new Button();runCmdBtn.Text = "运行命令";runCmdBtn.Size = new Size(80, 30);runCmdBtn.Click += new EventHandler(runCmdBtn_Click);buttonPanel.Controls.Add(refreshBtn);buttonPanel.Controls.Add(startBtn);buttonPanel.Controls.Add(killBtn);buttonPanel.Controls.Add(detailsBtn);buttonPanel.Controls.Add(runCmdBtn);mainLayout.Controls.Add(buttonPanel, 0, 3);mainLayout.SetColumnSpan(buttonPanel, 2);this.Controls.Add(mainLayout);this.ResumeLayout(false);}private void processListView_SelectedIndexChanged(object sender, EventArgs e){if (processListView.SelectedItems.Count > 0){int pid = int.Parse(processListView.SelectedItems[0].Text);UpdateProcessDetails(pid);}}private void refreshBtn_Click(object sender, EventArgs e){RefreshProcessList();}private void startBtn_Click(object sender, EventArgs e){StartProcess_Click(sender, e);}private void killBtn_Click(object sender, EventArgs e){KillProcess_Click(sender, e);}private void detailsBtn_Click(object sender, EventArgs e){ShowDetails_Click(sender, e);}private void runCmdBtn_Click(object sender, EventArgs e){RunCommand_Click(sender, e);}private void InitializeTimer(){refreshTimer = new Timer();refreshTimer.Interval = 5000; // 5秒刷新一次refreshTimer.Tick += new EventHandler(refreshTimer_Tick);refreshTimer.Start();}private void refreshTimer_Tick(object sender, EventArgs e){RefreshProcessList();}private void RefreshProcessList(){try{processListView.BeginUpdate();processListView.Items.Clear();Process[] processes = Process.GetProcesses();foreach (Process process in processes){try{ListViewItem item = new ListViewItem(process.Id.ToString());item.SubItems.Add(process.ProcessName);item.SubItems.Add((process.WorkingSet64 / 1024 / 1024).ToString());item.SubItems.Add(process.TotalProcessorTime.ToString(@"hh\:mm\:ss"));// .NET 4.0 中需要单独处理启动时间try{item.SubItems.Add(process.StartTime.ToString("yyyy-MM-dd HH:mm:ss"));}catch{item.SubItems.Add("N/A");}processListView.Items.Add(item);}catch (Exception ex){// 忽略无法访问的进程Debug.WriteLine("无法访问进程 " + process.Id + ": " + ex.Message);}}}catch (Exception ex){MessageBox.Show("刷新进程列表失败: " + ex.Message, "错误",MessageBoxButtons.OK, MessageBoxIcon.Error);}finally{processListView.EndUpdate();}}private void UpdateProcessDetails(int processId){try{string details = processMonitor.GetProcessDetails(processId);detailsTextBox.Text = details;}catch (Exception ex){detailsTextBox.Text = "获取进程详情失败: " + ex.Message;}}private void StartProcess_Click(object sender, EventArgs e){using (OpenFileDialog dialog = new OpenFileDialog()){dialog.Filter = "可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*";dialog.Title = "选择要启动的应用程序";if (dialog.ShowDialog() == DialogResult.OK){try{Process.Start(dialog.FileName);RefreshProcessList();}catch (Exception ex){MessageBox.Show("启动进程失败: " + ex.Message, "错误",MessageBoxButtons.OK, MessageBoxIcon.Error);}}}}private void KillProcess_Click(object sender, EventArgs e){if (processListView.SelectedItems.Count == 0){MessageBox.Show("请先选择一个进程", "提示",MessageBoxButtons.OK, MessageBoxIcon.Information);return;}int pid = int.Parse(processListView.SelectedItems[0].Text);string processName = processListView.SelectedItems[0].SubItems[1].Text;DialogResult result = MessageBox.Show("确定要终止进程 " + processName + " (PID: " + pid + ") 吗?","确认终止",MessageBoxButtons.YesNo,MessageBoxIcon.Warning);if (result == DialogResult.Yes){try{processMonitor.KillProcess(pid);RefreshProcessList();detailsTextBox.Clear();}catch (Exception ex){MessageBox.Show("终止进程失败: " + ex.Message, "错误",MessageBoxButtons.OK, MessageBoxIcon.Error);}}}private void ShowDetails_Click(object sender, EventArgs e){if (processListView.SelectedItems.Count > 0){int pid = int.Parse(processListView.SelectedItems[0].Text);UpdateProcessDetails(pid);}}private void RunCommand_Click(object sender, EventArgs e){string command = ShowInputDialog("请输入要执行的命令 (例如: ipconfig /all):", "运行命令", "ipconfig");if (!string.IsNullOrEmpty(command)){outputTextBox.Clear();processMonitor.StartProcessWithWait(command, outputTextBox);}}// .NET 4.0 兼容的输入对话框private string ShowInputDialog(string text, string caption, string defaultValue){Form prompt = new Form();prompt.Width = 400;prompt.Height = 150;prompt.Text = caption;prompt.FormBorderStyle = FormBorderStyle.FixedDialog;prompt.StartPosition = FormStartPosition.CenterScreen;prompt.MaximizeBox = false;prompt.MinimizeBox = false;Label textLabel = new Label() { Left = 20, Top = 20, Text = text, Width = 360 };TextBox textBox = new TextBox() { Left = 20, Top = 50, Width = 360, Text = defaultValue };Button confirmation = new Button() { Text = "确定", Left = 220, Width = 75, Top = 80 };Button cancel = new Button() { Text = "取消", Left = 305, Width = 75, Top = 80 };confirmation.Click += (s, e) => { prompt.DialogResult = DialogResult.OK; };cancel.Click += (s, e) => { prompt.DialogResult = DialogResult.Cancel; };prompt.Controls.Add(textLabel);prompt.Controls.Add(textBox);prompt.Controls.Add(confirmation);prompt.Controls.Add(cancel);prompt.AcceptButton = confirmation;prompt.CancelButton = cancel;if (prompt.ShowDialog() == DialogResult.OK){return textBox.Text;}return string.Empty;}protected override void Dispose(bool disposing){if (disposing){if (refreshTimer != null){refreshTimer.Stop();refreshTimer.Dispose();}}base.Dispose(disposing);}}
}
Form1.cs源码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace ProcessMonitorApp
{public partial class Form1 : Form{private ProcessMonitorControl processMonitor;public Form1(){InitializeComponent();InitializeCustomComponents();}private void InitializeCustomComponents(){// 创建进程监控控件processMonitor = new ProcessMonitorControl{Location = new Point(10, 10),Size = new Size(780, 450),Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right};this.Controls.Add(processMonitor);}private void Form1_Load(object sender, EventArgs e){this.Text = "高级进程监控器 - .NET 4.0";this.Size = new Size(800, 500);this.StartPosition = FormStartPosition.CenterScreen;}}
}
三、效果演示