使用C# winform 开发一个任务管理器

embedded/2025/1/2 16:46:36/

前言

为啥要开发这个呢 ,系统自带的关闭有些程序就关不了,它有好多线程,你关一其中一个它后台又重新开了一个,关不完,使用我这个呢 就把所有相同名称进程看作一个,一关就关

下载软件

v1


 

Form1.cs

using System;
using System.Windows.Forms;namespace TaskMaster
{public partial class Form1 : Form{// 全局变量用于跟踪上次点击的列和排序方向private DataGridViewColumn lastSortedColumn;private SortOrder lastSortOrder = SortOrder.None;TaskManager taskManager;public Form1(){InitializeComponent();// 实例化 TaskManagertaskManager = new TaskManager();//设置 DataGridView 的 Anchor 属性,确保它的大小会根据窗体的大小进行调整。你可以将 Anchor 设置为四个方向,使其随着窗口的拉伸或缩小进行动态调整。dataGridView1.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right);// 将进程信息加载到 dataGridView1taskManager.LoadProcessesIntoDataGridView(dataGridView1);// 绑定列头点击事件用于自定义排序dataGridView1.ColumnHeaderMouseClick += DataGridView_ColumnHeaderMouseClick;}/// <summary>/// 刷新/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){// 将进程信息加载到 dataGridView1taskManager.LoadProcessesIntoDataGridView(dataGridView1);}/// <summary>/// 检查是否右键点击/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void dataGridView1_MouseDown(object sender, MouseEventArgs e){// 检查是否右键点击if (e.Button == MouseButtons.Right){var hitTestInfo = dataGridView1.HitTest(e.X, e.Y);if (hitTestInfo.RowIndex >= 0){// 选中行dataGridView1.Rows[hitTestInfo.RowIndex].Selected = true;// 动态创建并显示上下文菜单ContextMenuStrip contextMenu = new ContextMenuStrip();ToolStripMenuItem closeProcessItem = new ToolStripMenuItem("关闭进程");closeProcessItem.Click += CloseProcessItem_Click;contextMenu.Items.Add(closeProcessItem);contextMenu.Show(dataGridView1, e.Location);}}}/// <summary>/// 点击终止进程/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void CloseProcessItem_Click(object sender, EventArgs e){// 获取选中行的进程名称if (dataGridView1.SelectedRows.Count > 0){var selectedRow = dataGridView1.SelectedRows[0];string processName = selectedRow.Cells["ProcessName"].Value.ToString();// 终止进程taskManager.KillProcessesByName(processName);// 重新加载进程列表taskManager.LoadProcessesIntoDataGridView(dataGridView1);}}// 列头点击事件,用于自定义排序private void DataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e){DataGridView dataGridView = sender as DataGridView;// 获取当前点击的列DataGridViewColumn clickedColumn = dataGridView.Columns[e.ColumnIndex];// 如果点击的是上次排序的列,切换排序方向SortOrder sortOrder;if (clickedColumn == lastSortedColumn){sortOrder = lastSortOrder == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;}else{// 如果是新列,默认升序排序sortOrder = SortOrder.Ascending;}// 根据列名执行不同的自定义排序逻辑if (clickedColumn.Name == "MemoryUsage"){dataGridView.Sort(new MemoryUsageComparer());}else if (clickedColumn.Name == "CpuTime"){dataGridView.Sort(new CpuTimeComparer());}else{// 默认的列使用内置排序dataGridView.Sort(clickedColumn, sortOrder == SortOrder.Ascending? System.ComponentModel.ListSortDirection.Ascending: System.ComponentModel.ListSortDirection.Descending);}// 保存当前排序的列和方向lastSortedColumn = clickedColumn;lastSortOrder = sortOrder;}}}

TaskManager.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;namespace TaskMaster
{public class TaskManager{// 获取所有正在运行的进程并直接绑定到传入的 DataGridViewpublic void LoadProcessesIntoDataGridView(DataGridView dataGridView){// 清除现有的数据dataGridView.Rows.Clear();dataGridView.Columns.Clear();// 设置 DataGridView 属性dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;dataGridView.AllowUserToAddRows = false;dataGridView.RowTemplate.Height = 50;// 创建一个新的 DataGridViewImageColumnDataGridViewImageColumn imageColumn = new DataGridViewImageColumn{HeaderText = "图标",Name = "IconColumn",ImageLayout = DataGridViewImageCellLayout.Normal};dataGridView.Columns.Add(imageColumn);// 添加其他数据列dataGridView.Columns.Add("ProcessName", "进程名");dataGridView.Columns.Add("PID", "进程ID");dataGridView.Columns.Add("MemoryUsage", "内存使用 (KB)");dataGridView.Columns.Add("CpuTime", "CPU时间");// 用于存储已经显示的进程名称HashSet<string> displayedProcesses = new HashSet<string>();// 获取所有进程Process[] processes = Process.GetProcesses();foreach (var process in processes){try{// 只显示尚未显示的进程if (!displayedProcesses.Contains(process.ProcessName)){// 获取进程的可执行文件路径string filePath = process.MainModule.FileName;// 获取进程图标Icon processIcon = GetProcessIcon(filePath);Bitmap iconBitmap = processIcon.ToBitmap();// 创建新行并设置图像及其他数据int rowIndex = dataGridView.Rows.Add();DataGridViewRow row = dataGridView.Rows[rowIndex];row.Cells["IconColumn"].Value = iconBitmap;row.Cells["ProcessName"].Value = process.ProcessName;row.Cells["PID"].Value = process.Id;row.Cells["MemoryUsage"].Value = FormatMemorySize(process.WorkingSet64);row.Cells["CpuTime"].Value = FormatCpuTime(process.TotalProcessorTime);// 记录已显示的进程名displayedProcesses.Add(process.ProcessName);}}catch (Exception ex){Console.WriteLine($"无法读取进程 {process.ProcessName}: {ex.Message}");}}}/// <summary>///  格式化 CPU 时间,如果小时或分钟为 0 则不显示它们/// </summary>/// <param name="cpuTime"></param>/// <returns></returns>private string FormatCpuTime(TimeSpan cpuTime){int hours = cpuTime.Hours;int minutes = cpuTime.Minutes;int seconds = cpuTime.Seconds;int milliseconds = cpuTime.Milliseconds;// 使用 StringBuilder 动态构建时间字符串StringBuilder formattedTime = new StringBuilder();if (hours > 0){formattedTime.Append($"{hours}H");}if (minutes > 0 || hours > 0) // 如果有小时,即使分钟为 0 也显示{formattedTime.Append($"{minutes}M");}if (seconds > 0 || minutes > 0 || hours > 0) // 如果有分钟或小时,即使秒为 0 也显示{formattedTime.Append($"{seconds}S");}// 毫秒总是显示formattedTime.Append($"{milliseconds}MS");return formattedTime.ToString();}/// <summary>/// 将内存大小转换为合适的单位/// </summary>/// <param name="bytes"></param>/// <returns></returns>private string FormatMemorySize(long bytes){const double KB = 1024;const double MB = KB * 1024;const double GB = MB * 1024;if (bytes >= GB){return $"{(bytes / GB):F2} GB";}else if (bytes >= MB){return $"{(bytes / MB):F2} MB";}else if (bytes >= KB){return $"{(bytes / KB):F2} KB";}else{return $"{bytes} B";}}/// <summary>/// 获取进程图标/// </summary>/// <param name="filePath"></param>/// <returns></returns>private Icon GetProcessIcon(string filePath){try{// 使用 Icon.ExtractAssociatedIcon 方法获取文件图标return Icon.ExtractAssociatedIcon(filePath);}catch{// 如果获取图标失败,返回一个默认图标return SystemIcons.Application; // 使用默认图标}}// 根据进程 ID 终止进程public bool KillProcess(int processId){try{Process process = Process.GetProcessById(processId);process.Kill();return true;}catch (Exception ex){Console.WriteLine($"无法终止进程 {processId}: {ex.Message}");return false;}}// 根据进程名称终止所有匹配的进程public bool KillProcessesByName(string processName){try{// 查找所有与指定名称匹配的进程Process[] processes = Process.GetProcessesByName(processName);if (processes.Length == 0){Console.WriteLine($"没有找到名为 {processName} 的进程。");return false;}// 终止所有匹配的进程foreach (var process in processes){process.Kill();}Console.WriteLine($"已终止所有名为 {processName} 的进程。");return true;}catch (Exception ex){Console.WriteLine($"无法终止进程 {processName}: {ex.Message}");return false;}}}
}

工程源码

v1


http://www.ppmy.cn/embedded/125011.html

相关文章

MAC备忘录空白解决方案

打开icloud->备忘录 取消勾选同步此MAC后再次勾选&#xff0c;然后点击完成即可。

消息队列(如RabbitMQ、Kafka)的使用与原理。缓存系统(如Redis、Memcached)的使用与优化。

消息队列&#xff08;如RabbitMQ、Kafka&#xff09;的使用与原理。 消息队列是一种分布式系统中的设计模式&#xff0c;它允许系统中的不同组件通过异步的方式交换信息。以下是RabbitMQ和Kafka这两种消息队列的使用与原理的详细介绍&#xff1a; 一、消息队列的基本概念 消…

LabVIEW惯性导航系统仿真平台

LabVIEW开发捷联惯性导航系统仿真平台&#xff0c;采用模块化设计&#xff0c;利用LabVIEW的图形化编程特性&#xff0c;提高了系统仿真的效率和精度&#xff0c;同时具备良好的可扩展性和用户交互性。 项目背景 当前&#xff0c;惯性导航系统&#xff08;INS&#xff09;的研…

【机器学习】监督学习 vs 非监督学习——如何选择合适的方法

【机器学习】监督学习 vs 非监督学习——如何选择合适的方法 1. 引言 在机器学习中&#xff0c;算法大致可以分为两类&#xff1a;监督学习&#xff08;Supervised Learning&#xff09;和非监督学习&#xff08;Unsupervised Learning&#xff09;。它们的区别主要在于是否提…

2024.10.8 作业+思维导图

优化登录框&#xff1a; 当用户点击取消按钮&#xff0c;弹出问题对话框&#xff0c;询问是否要确定退出登录&#xff0c;并提供两个按钮&#xff0c;yes|No&#xff0c;如果用户点击的Yes&#xff0c;则关闭对话框&#xff0c;如果用户点击的No&#xff0c;则继续登录 当用户点…

Golang正则表达式详解:regexp包的应用与最佳实践

Golang正则表达式详解&#xff1a;regexp包的应用与最佳实践 引言基本概念与正则表达式基础正则表达式简介基本语法和字符普通字符元字符 常用的正则表达式模式示例 regexp 包的基本用法导入 regexp 包编译正则表达式CompileMustCompile 简单匹配MatchMatchString 示例 高级匹配…

深度学习——生成对抗网络(GAN)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

[Algorithm][贪心][整数替换][俄罗斯套娃信封问题]详细讲解

目录 1.整数替换1.题目链接2.算法原理详解1.解法一2.解法二 3.代码实现1.代码一2.代码二 2.俄罗斯套娃信封问题1.题目链接2.算法原理详解1.解法一2.解法二 3.代码实现1.代码一2.代码二 1.整数替换 1.题目链接 整数替换 2.算法原理详解 1.解法一 思路&#xff1a;模拟(递归 …