文章的目的为了记录使用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.效果演示
一、源码分析
- 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;
}
功能分析:
设置窗体标题
设置窗体初始大小
设置窗体启动位置为屏幕中央
- 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;
// ... 对话框构建代码
}
功能分析:
动态创建输入对话框窗体
包含标签、文本框、确定取消按钮
返回用户输入的命令字符串
- 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 中需要安全地访问 MainModule
try
{
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;
}
}
}
三、效果演示
