WPF开发之C#中关闭进程的方式(Process)

根据名称关闭

使用C#结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static void StopNginx()
{
Process[] processes = Process.GetProcessesByName("nginx");
foreach (Process p in processes)
{
string basePath = AppDomain.CurrentDomain.BaseDirectory;
string nginxPath = System.IO.Path.Combine(basePath, "Nginx", "nginx.exe");
if (nginxPath == p.MainModule.FileName)
{
p.Kill();
p.Close();
}
}
}

注意

进程名称不要写成nginx.exe,会找不到nginx进程。

本来我还尝试了用进程对象来结束,但是不行,因为Nginx启动会产生多个进程,单独结束掉一个是不行的!

根据端口号关闭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace SchoolClient.Utils
{
internal class ZProcessUtil
{
public static void closeProcess(int port)
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
List<int> list_pid = GetPidByPort(p, port);
if (list_pid.Count == 0)
{
return;
}
List<string> list_process = GetProcessNameByPid(p, list_pid);
StringBuilder sb = new StringBuilder();
sb.AppendLine("占用" + port + "端口的进程有:");
foreach (var item in list_process)
{
sb.Append(item + "\r\n");
}
Console.WriteLine(sb.ToString());

PidKill(p, list_pid);
}

/// <summary>
/// 根据PID杀掉进程
/// </summary>
/// <param name="p"></param>
/// <param name="list_pid"></param>
private static void PidKill(Process p, List<int> list_pid)
{
p.Start();
foreach (var item in list_pid)
{
p.StandardInput.WriteLine("taskkill /pid " + item + " /f");
p.StandardInput.WriteLine("exit");
}
p.Close();
}

/// <summary>
/// 根据端口号获取进程ID
/// </summary>
/// <param name="p"></param>
/// <param name="port"></param>
/// <returns></returns>
private static List<int> GetPidByPort(Process p, int port)
{
int result;
bool b = true;
p.Start();
p.StandardInput.WriteLine(string.Format("netstat -ano|findstr {0}", port));
p.StandardInput.WriteLine("exit");
StreamReader reader = p.StandardOutput;
string strLine = reader.ReadLine();
List<int> list_pid = new List<int>();
while (!reader.EndOfStream)
{
strLine = strLine.Trim();
if (strLine.Length > 0 && ((strLine.Contains("TCP") || strLine.Contains("UDP"))))
{
Regex r = new Regex(@"\s+");
string[] strArr = r.Split(strLine);
if (strArr.Length >= 4)
{
b = int.TryParse(strArr[4], out result);
if (b && !list_pid.Contains(result))
list_pid.Add(result);
}
}
strLine = reader.ReadLine();
}
p.WaitForExit();
reader.Close();
p.Close();
return list_pid;
}

/// <summary>
/// 根据PID获取进程名
/// </summary>
/// <param name="p"></param>
/// <param name="list_pid"></param>
/// <returns></returns>
private static List<string> GetProcessNameByPid(Process p, List<int> list_pid)
{
p.Start();
List<string> list_process = new List<string>();
foreach (var pid in list_pid)
{
p.StandardInput.WriteLine(string.Format("tasklist |findstr \"{0}\"", pid));
p.StandardInput.WriteLine("exit");
StreamReader reader = p.StandardOutput;//截取输出流
string strLine = reader.ReadLine();//每次读取一行

while (!reader.EndOfStream)
{
strLine = strLine.Trim();
if (strLine.Length > 0 && ((strLine.Contains(".exe"))))
{
Regex r = new Regex(@"\s+");
string[] strArr = r.Split(strLine);
if (strArr.Length > 0)
{
list_process.Add(strArr[0]);
}
}
strLine = reader.ReadLine();
}
p.WaitForExit();
reader.Close();
}
p.Close();

return list_process;
}
}
}

其实就是用CMD获取占用端口的进程ID

1
netstat -ano|findstr ":10077 "

比如进程ID为16212

查看进程对应的进程名称

1
tasklist |findstr 16212

结束进程

1
taskkill /f /pid 16212