查询与指定端口相关的进程列表,并提供杀进程按钮.实际内容为将控制台命令"netstat"数据解析显示为列表,并提供杀进程的按钮;
public class PortUserInfo
{
/// <summary>
/// 端口协议类型,TCP,UDP等
/// </summary>
public string Type;
/// <summary>
/// 端口状态
/// </summary>
public string State;
/// <summary>
/// 本地终端地址
/// </summary>
public string LocolEndPoint;
/// <summary>
/// 本地IP
/// </summary>
public IPAddress LocolIPAddress;
/// <summary>
/// 本地端口
/// </summary>
public int LocolPort;
/// <summary>
/// 远程终端地址
/// </summary>
public string RemoteEndPoint;
/// <summary>
/// 占用端口的进程ID
/// </summary>
public int Pid;
/// <summary>
/// 占用端口的进程
/// </summary>
public Process Process;
/// <summary>
/// 占用端口的进程进程名
/// </summary>
public string ProcessName;
}
public class WhoUsePort
{
/// <summary>
/// 根据netstat命令找到占用端口的进程id,并返回占用进程对象信息
/// </summary>
/// <param name="port">端口</param>
/// <returns></returns>
public static PortUserInfo[] NetStatus(int port,bool strict=false)
{
string strInput = $"echo off&netstat -aon|findstr \"{port}\"&exit";
Process p = new Process();
//设置要启动的应用程序
p.StartInfo.FileName = "cmd.exe";
//是否使用操作系统shell启动
p.StartInfo.UseShellExecute = false;
// 接受来自调用程序的输入信息
p.StartInfo.RedirectStandardInput = true;
//输出信息
p.StartInfo.RedirectStandardOutput = true;
// 输出错误
p.StartInfo.RedirectStandardError = true;
//不显示程序窗口
p.StartInfo.CreateNoWindow = true;
//启动程序
p.Start();
//向cmd窗口发送输入信息
p.StandardInput.WriteLine(strInput);
p.StandardInput.AutoFlush = true;
//获取输出信息
string strOuput = p.StandardOutput.ReadToEnd();
//等待程序执行完退出进程
p.WaitForExit();
p.Close();
int index = strOuput.IndexOf(strInput);
string reply = strOuput.Remove(0, index strInput.Length);
List<PortUserInfo> processes = new List<PortUserInfo>();
string[] sp = new string[] { "\r\n" };
string[] infos = reply.Split(sp, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in infos)
{
sp = new string[] { " " };
string[] column = line.Split(sp, StringSplitOptions.RemoveEmptyEntries);
if (column.Length >= 5)
{
PortUserInfo pinfo = new PortUserInfo();
pinfo.Type = column[0];
pinfo.LocolEndPoint = column[1];
int portindex = column[1].IndexOf(":") 1;
int cnt = column[1].Length - portindex;
string ipstring = column[1].Substring(0, portindex - 1);
string portstring = column[1].Substring(portindex, cnt);
if (IPAddress.TryParse(ipstring, out IPAddress localip))
{
pinfo.LocolIPAddress = localip;
}
if (int.TryParse(portstring, out int localport))
{
pinfo.LocolPort = localport;
}
if (strict)
{
if (localport!=port)
{
continue;
}
}
pinfo.RemoteEndPoint = column[2];
pinfo.State = column[3];
string pidstring = column[4];
if (int.TryParse(pidstring, out int pid))
{
pinfo.Pid = pid;
try
{
Process proc = Process.GetProcessById(pid);
pinfo.Process = proc;
pinfo.ProcessName = proc.ProcessName;
processes.Add(pinfo);
}
catch
{
//发生异常,如进程未启动
}
}
}
}
return processes.ToArray();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnSearch_Click(object sender, EventArgs e)
{
int port = (int)numericUpDown1.Value;
var proc = WhoUsePort.NetStatus(port,checkBox1.Checked);
dataGridView1.Rows.Clear();
foreach (var p in proc)
{
int index = dataGridView1.RowCount;
dataGridView1.Rows.Insert(index, new string[] { "",
p.ProcessName,
p.Pid.ToString(),
p.LocolPort.ToString(),
p.Type,
p.State,
p.LocolEndPoint,
p.RemoteEndPoint
});
dataGridView1.Rows[index].Tag = p.Process;
}
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int row = e.RowIndex;
int col = e.ColumnIndex;
if (row < 0 || row < 0)
{
return;
}
if (dataGridView1.Columns[col] == Column1)
{//杀进程
if (dataGridView1.Rows[row].Tag is Process p)
{
string msg = $"确认结束进程[{p.ProcessName}]:[pid={p.Id}]吗?\r\n请确认结束进程的不会带来严重后果.";
var dr = MessageBox.Show(msg, "警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (dr == DialogResult.OK)
{
p.Kill();
dataGridView1.Rows.Remove(dataGridView1.Rows[row]);
}
}
}
}
}
评论