实验4 进程管理
实验内容
1、复现代码(参考例6-1)
获取本机所有进程信息。
2、增加结束进程功能
下方增加结束进程按钮,点击按钮,结束选中进程。
3、增加启动进程功能
下方增加启动进程按钮,弹出模式对话框窗体,实现类似功能。界面仅为推荐不限制,可以根据全路径信息,启动进程即可。
窗体展示
主窗体展示
启动进程窗体展示
代码参考
主窗体代码
//From:TengMMVP
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProcessForm
{
public partial class Form_MainWindow : Form
{
//主窗体初始化
public Form_MainWindow()
{
InitializeComponent();
}
//窗体事件:主窗体加载时刷新进程信息
private void Form_MainWindow_Load(object sender, EventArgs e)
{
RefreshProcesses();
}
//鼠标事件:选中指定行,调用详细信息展示函数
private void dataGridView_ShowProcess_MouseClick(object sender, MouseEventArgs e)
{
// 使用HitTest方法来确定鼠标点击在DataGridView的哪个部分
DataGridView.HitTestInfo h = dataGridView_ShowProcess.HitTest(e.X, e.Y);
// 判断点击的是否是单元格或行头
if (h.Type == DataGridViewHitTestType.Cell || h.Type == DataGridViewHitTestType.RowHeader)
{
// 设置点击行为选中状态
dataGridView_ShowProcess.Rows[h.RowIndex].Selected = true;
// 从当前选中行的第一个单元格中获取进程ID
int processId = (int)dataGridView_ShowProcess.CurrentRow.Cells[0].Value;
try
{
// 尝试根据进程ID获取进程信息
Process process = Process.GetProcessById(processId);
// 显示进程信息
ShowProcessInfo(process);
}
catch (ArgumentException ex)
{
// 捕获异常,并显示错误消息框告知用户无法获取进程信息
MessageBox.Show($"无法获取进程信息:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
//展示详细进程信息
private void ShowProcessInfo(Process p)
{
listBox_ShowDetail.Items.Clear();
listBox_ShowDetail.Items.Add($"进程名称:{p.ProcessName},ID:{p.Id}");
try
{
listBox_ShowDetail.Items.Add($"进程优先级:{p.BasePriority} (优先级类别:{p.PriorityClass})");
ProcessModule m = p.MainModule;
if (m != null)
{
listBox_ShowDetail.Items.Add($"文件名:{m.FileName}");
listBox_ShowDetail.Items.Add($"版本:{m.FileVersionInfo.FileVersion}");
listBox_ShowDetail.Items.Add($"描述:{m.FileVersionInfo.FileDescription}");
listBox_ShowDetail.Items.Add($"语言:{m.FileVersionInfo.Language}");
listBox_ShowDetail.Items.Add("------------------------");
}
if (p.Modules != null)
{
ProcessModuleCollection pmc = p.Modules;
listBox_ShowDetail.Items.Add("调用的模块(.dll):");
for (int i = 1; i < pmc.Count; i++)
{
listBox_ShowDetail.Items.Add(
"模块名:" + pmc[i].ModuleName + " " +
"版本:" + pmc[i].FileVersionInfo.FileVersion + " " +
"描述:" + pmc[i].FileVersionInfo.FileDescription);
}
}
}
catch
{
listBox_ShowDetail.Items.Add("其他信息:无法获取");
}
}
//鼠标事件:打开启动进程的窗体,并刷新进程信息
private async void button_StartProcess_Click(object sender, EventArgs e)
{
// 使用using语句来确保StartProcessForm对象在使用完毕后能够被正确释放
using (StartProcessForm startProcessForm = new StartProcessForm())
{
// 订阅StartProcessForm的ProcessStarted事件
// 当该事件被触发时,会执行下面的Lambda表达式
startProcessForm.ProcessStarted += (s, args) =>
{
// 对话框操作完成后,等待1秒然后刷新进程列表
Task.Delay(1000).ContinueWith(t =>
{
// 由于更新UI的操作需要在UI线程上执行,所以使用this.Invoke来确保RefreshProcesses方法在UI线程上被调用
// 这里使用了一个Action委托来封装RefreshProcesses方法的调用
this.Invoke(new Action(() =>
{
RefreshProcesses();
}));
});
};
// 显示StartProcessForm对话框,并等待用户操作完成
startProcessForm.ShowDialog();
}
}
//鼠标事件:关闭指定进程
private void button_EndProcess_Click(object sender, EventArgs e)
{
if (dataGridView_ShowProcess.CurrentRow == null) return;
int selectedRowIndex = dataGridView_ShowProcess.CurrentRow.Index;
if (selectedRowIndex < 0) return;
int processId = Convert.ToInt32(dataGridView_ShowProcess.Rows[selectedRowIndex].Cells["Column_ProcessID"].Value);
try
{
Process process = Process.GetProcessById(processId);
// 首先尝试使用CloseMainWindow正常关闭进程
bool closeSucceeded = process.CloseMainWindow();
if (!closeSucceeded)
{
// 如果CloseMainWindow方法失败,使用Kill方法强制结束进程
process.Kill();
}
// 等待进程退出,设置一个合理的超时
process.WaitForExit(1000); // 等待1秒
// 刷新进程列表
RefreshProcesses();
}
catch (InvalidOperationException ex)
{
// 处理进程已退出的异常
MessageBox.Show($"进程已经退出,无需结束。错误信息:{ex.Message}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
RefreshProcesses();
}
catch (Exception ex)
{
// 处理其他可能的异常
MessageBox.Show($"无法结束进程: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
//刷新进程信息
private void RefreshProcesses()
{
dataGridView_ShowProcess.Rows.Clear();
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
string startTime = "N/A";
string fileName = "N/A";
string memoryUsage = "N/A";
try
{
startTime = process.StartTime.ToString("g");
fileName = process.MainModule.FileName;
memoryUsage = string.Format("{0:###,##0.00} MB", process.WorkingSet64 / 1024.0f / 1024.0f);
}
catch (System.ComponentModel.Win32Exception ex)
{
// 这可能是由于没有足够的权限来访问进程信息
Debug.WriteLine($"无法访问进程信息: {ex.Message}");
// 可以在这里设置一些默认值或者特殊的标记
fileName = "权限不足";
}
catch (System.InvalidOperationException ex)
{
// 这可能是因为进程已经退出
Debug.WriteLine($"进程可能已退出: {ex.Message}");
// 对于已退出的进程,可能无法获取启动时间等信息
startTime = "进程已退出";
}
catch (Exception ex)
{
// 捕获其他所有异常
Debug.WriteLine($"获取进程信息时发生未知错误: {ex.Message}");
// 设置为通用错误信息
fileName = "未知错误";
startTime = "未知错误";
}
dataGridView_ShowProcess.Rows.Add(process.Id, process.ProcessName, memoryUsage, startTime, fileName);
}
}
}
}
//From:TengMMVP
启动进程窗体代码
//From:TengMMVP
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;
using System.Diagnostics;
namespace ProcessForm
{
public partial class StartProcessForm : Form
{
public event EventHandler ProcessStarted;
public StartProcessForm()
{
InitializeComponent();
}
protected virtual void OnProcessStarted()
{
ProcessStarted?.Invoke(this, EventArgs.Empty);
}
private void button_OK_Click(object sender, EventArgs e)
{
try
{
string processName = comboBox_Chose.Text;
Process.Start(processName);
OnProcessStarted();
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("无法启动指定的程序或打开文件/文件夹。错误信息:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button_Cancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void button_Search_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Title = "浏览";
dialog.InitialDirectory = "c:\\"; // 设置初始目录
// 设置文件过滤器
dialog.Filter = "程序 (*.exe;*.pif;*.com;*.bat;*.cmd)|*.exe;*.pif;*.com;*.bat;*.cmd|所有文件 (*.*)|*.*";
dialog.FilterIndex = 1; // 默认选择第一个过滤器
dialog.RestoreDirectory = true; // 在关闭对话框后还原当前目录
if (dialog.ShowDialog() == DialogResult.OK)
{
// 获取选定文件的路径
string filePath = dialog.FileName;
// 将文件路径设置到下拉框中
comboBox_Chose.Text = filePath;
}
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// 添加选项到下拉框
string[] options = { "notepad.exe", "cmd.exe" };
comboBox_Chose.Items.AddRange(options);
// 可以选择设置一个默认选项
if (comboBox_Chose.Items.Count > 0)
{
comboBox_Chose.SelectedIndex = 0;
}
}
}
}
//From:TengMMVP