前言
为啥要开发这个呢 ,系统自带的关闭有些程序就关不了,它有好多线程,你关一其中一个它后台又重新开了一个,关不完,使用我这个呢 就把所有相同名称进程看作一个,一关就关
下载软件
Form1.cs
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();
// 实例化 TaskManager
taskManager = new TaskManager();
//设置 DataGridView 的 Anchor 属性,确保它的大小会根据窗体的大小进行调整。你可以将 Anchor 设置为四个方向,使其随着窗口的拉伸或缩小进行动态调整。
dataGridView1.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right);
// 将进程信息加载到 dataGridView1
taskManager.LoadProcessesIntoDataGridView(dataGridView1);
// 绑定列头点击事件用于自定义排序
dataGridView1.ColumnHeaderMouseClick += DataGridView_ColumnHeaderMouseClick;
}
/// <summary>
/// 刷新
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
// 将进程信息加载到 dataGridView1
taskManager.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
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
{
// 获取所有正在运行的进程并直接绑定到传入的 DataGridView
public void LoadProcessesIntoDataGridView(DataGridView dataGridView)
{
// 清除现有的数据
dataGridView.Rows.Clear();
dataGridView.Columns.Clear();
// 设置 DataGridView 属性
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.AllowUserToAddRows = false;
dataGridView.RowTemplate.Height = 50;
// 创建一个新的 DataGridViewImageColumn
DataGridViewImageColumn 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;
}
}
}
}