开源 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;
}

功能分析:

设置窗体标题

设置窗体初始大小

设置窗体启动位置为屏幕中央

  1. 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;
    // ... 对话框构建代码
}

功能分析:

动态创建输入对话框窗体

包含标签、文本框、确定取消按钮

返回用户输入的命令字符串

  1. 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;
        }
    }
}

三、效果演示

相关推荐
库库8393 小时前
Java微服务知识点详细总结
java·开发语言·微服务
txwtech3 小时前
第4篇 vs2019+QT调用SDK连接海康相机显示图片
开发语言·数码相机·qt
FIT2CLOUD飞致云3 小时前
飞致云开源社区月度动态报告(2025年9月)
人工智能·开源
王嘉俊9253 小时前
Flask 入门:轻量级 Python Web 框架的快速上手
开发语言·前端·后端·python·flask·入门
做运维的阿瑞3 小时前
Python 面向对象编程深度指南
开发语言·数据结构·后端·python
木木子99993 小时前
Python的typing模块:类型提示 (Type Hinting)
开发语言·windows·python
她说人狗殊途4 小时前
Spring IoC容器加载过程 vs Bean生命周期对应关系图
java·开发语言·rpc
MediaTea4 小时前
Python 编辑器:PyCharm
开发语言·ide·python·pycharm·编辑器
0wioiw04 小时前
Go基础(⑦实例和依赖注入)
开发语言·golang