c#网络编程实战笔记1-进程管理
1. 相关概念
进程是对一段静态指令序列(程序)的动态执行过程。与进程相关的信息包括进程的用户标志、正在执行的已经编译好的程序、进程程序、数据在存储器中的位置等。当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源,当然一个程序也可能开启多个进程。而一个进程又是由多个线程所组成的。
在System.Diagnostics命名空间下,有一个Process类,用于完成与进程相关的处理任务。
一个应用程序执行时调用其他的应用程序,实际上就是对进程进行管理。
初始化Process组件后,可使用该组件来获取有关当前运行的进程的信息。如进程包含的线程集、加载的模块(.dll文件)以及进程当前使用的内存量。
2. 获取进程信息
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Diagnostics; 6 7 namespace test 8 { 9 class Program 10 { 11 /// <summary> 12 /// 获取本地计算机的所有进程的信息 13 /// ------------------------------------------ 14 ///-------------------------------------------------------------------------- 15 ///p.Id:获取关联进程的唯一标识符 16 ///p.ProcessName:获取该进程的名称,该名称不包括文件扩展名和路径 17 ///p.WorkingSet64:获取为进程分配的物理内存量(字节数) 18 ///p.BasePriority:获取进程优先级(只读),取值如下:4-表示空闲优先级(Idle),即此进程中的线程只能在系统空闲时运行,如屏幕保护程序等。更高优先级类中运行的任何进程中的线程都优先于此进程中的线程,8-表示Normal优先级,13-表示High优先级,即进程必须立即执行的时间关键任务,该进程中的线程优先于普通或空闲优先级进程中的线程,24-表示RealTime优先级,它指定进程拥有可能的最高优先级,由于此优先级最高,当该进程耗时较长时,可能导致磁盘缓存不刷新,或导致鼠标无响应,所以一般不使用此优先级。 19 ///p.PagedSystemMemorySize64:获取为关联的进程分配的可分页系统内存量 20 ///p.PagedMemorySize64:获取为关联的进程分配的分页内存量 21 ///p.PriorityClass:设置或更改进程优先级,枚举值有6个:Idle、Normal、High、AboveNormal、BelowNormal、RealTime 22 ///p.UserProcessorTime:获取此进程的用户处理器时间 23 ///p.PrivilegedProcessorTime:获取此进程的特权处理器时间 24 ///p.TotalProcessorTime:获取此进程的总的处理时间,此值是UserProcessorTime和PrivilegedProcessorTime的和。 25 ///p.StartTime:获取关联进程启动的时间 26 ///p.MainModule 27 ///p.MainModule.FileName:文件名。每个进程都包含一个ProcessModuleCollection类型的Modules集合,该集合包含了与进程相关的信息。但是要注意,由于并不是每个进程都能获取Modules集合,所以获取该集合时必须要使用try/catch语句捕获可能出现的异常。该集合的第一个成员等同于MainModule属性,MainModule中的FileName属性包含了进程的完整文件名;集合中的其他成员包含该进程调用的.dll文件信息,像反木马程序就是利用这些成员得到需要的结果。 28 ///p.MainModule.FileVersionInfo.FileVersion:版本 29 ///p.MainModule.FileVersionInfo.FileDescription:描述 30 ///p.MainModule.FileVersionInfo.Language:语言 31 ///p.Modules 32 ///p.Modules.ModuleName:模块名 33 ///p.Modules.FileVersionInfo.FileVersion:版本 34 ///p.Modules.FileVersionInfo.FileDescription:描述 35 /// -------------------------------------------------------------------------- 36 /// ------------------------------------------- 37 /// </summary> 38 /// <param name="args"></param> 39 /// 输出: 40 ///-------------------------------------------------------------------------- 41 ///p.Id:3880 42 ///p.ProcessName:UNS 43 ///p.WorkingSet64 / 1024.0f / 1024.0f:5.84MB 44 ///p.BasePriority:8 45 ///p.PagedSystemMemorySize64:78252 46 ///p.PagedMemorySize64:4079616 47 ///p.PriorityClass:Normal 48 ///p.UserProcessorTime:00:00:00.0468750 49 ///p.PrivilegedProcessorTime:00:00:00.0937500 50 ///p.TotalProcessorTime:00:00:00.1406250 51 ///p.StartTime:2013-7-5 7:48:14 52 ///------------------------- 53 ///文件名:C:\Program Files\Intel\Intel(R) Management Engine Components\UNS\UNS.exe 54 ///版本:7.1.2.1043 55 ///描述:User Notification Service 56 ///语言:英语(美国) 57 ///调用的模块(.dll): 58 ///模块名:ntdll.dll 版本:5.1.2600.6055 (xpsp_sp3_gdr.101209-1647) 描述:NT Layer DLL 59 ///模块名:kernel32.dll 版本:5.1.2600.6293 (xpsp_sp3_gdr.121001-1622) 描述:Windows NT BASE API Client DLL 60 ///模块名:WSOCK32.dll 版本:5.1.2600.5512 (xpsp.080413-0852) 描述:Windows Socket 32-Bit DLL 61 ///模块名:WS2_32.dll 版本:5.1.2600.5512 (xpsp.080413-0852) 描述:Windows Socket 2.0 32-Bit DLL 62 ///模块名:ADVAPI32.dll 版本:5.1.2600.5755 (xpsp_sp3_gdr.090206-1234) 描述:Advanced Windows 32 Base API 63 ///模块名:RPCRT4.dll 版本:5.1.2600.6022 (xpsp_sp3_gdr.100813-1643) 描述:Remote Procedure Call Runtime 64 ///模块名:Secur32.dll 版本:5.1.2600.5834 (xpsp_sp3_gdr.090624-1305) 描述:Security Support Provider Interface 65 ///模块名:msvcrt.dll 版本:7.0.2600.5512 (xpsp.080413-2111) 描述:Windows NT CRT DLL 66 ///模块名:WS2HELP.dll 版本:5.1.2600.5512 (xpsp.080413-0852) 描述:Windows Socket 2.0 Helper for Windows NT 67 ///模块名:CRYPT32.dll 版本:5.131.2600.6239 (xpsp_sp3_gdr.120601-1620) 描述:Crypto API32 68 ///模块名:MSASN1.dll 版本:5.1.2600.5875 (xpsp_sp3_gdr.090904-1413) 描述:ASN.1 Runtime APIs 69 ///模块名:USER32.dll 版本:5.1.2600.5512 (xpsp.080413-2105) 描述:Windows XP USER API Client DLL 70 ///模块名:GDI32.dll 版本:5.1.2600.5698 (xpsp_sp3_gdr.081022-1932) 描述:GDI Client DLL 71 ///模块名:IPHLPAPI.DLL 版本:5.1.2600.5512 (xpsp.080413-0852) 描述:IP Helper API 72 ///模块名:WINHTTP.dll 版本:5.1.2600.6175 (xpsp_sp3_gdr.111116-1647) 描述:Windows HTTP Services 73 ///模块名:SHLWAPI.dll 版本:6.00.2900.5912 (xpsp_sp3_gdr.091207-1454) 描述:Shell Light-weight Utility Library 74 ///模块名:SETUPAPI.dll 版本:5.1.2600.5512 (xpsp.080413-2111) 描述:Windows Setup API 75 ///模块名:StatusStrings.dll 版本:3.0.0.1 描述:Intel(R) Active Management Technology StatusStrings DLL 76 ///模块名:xerces-c_2_7.dll 版本:2, 7, 0 描述:Shared Library for Xerces-C Version 2.7.0 77 ///模块名:VERSION.dll 版本:5.1.2600.5512 (xpsp.080413-2105) 描述:Version Checking and File Installation Libraries 78 ///模块名:SHELL32.dll 版本:6.00.2900.6242 (xpsp_sp3_gdr.120608-1638) 描述:Windows Shell Common Dll 79 ///模块名:ole32.dll 版本:5.1.2600.6168 (xpsp_sp3_gdr.111101-1829) 描述:Microsoft OLE for Windows 80 ///模块名:OLEAUT32.dll 版本:5.1.2600.6341 描述: 81 ///模块名:IMM32.DLL 版本:5.1.2600.5512 (xpsp.080413-2105) 描述:Windows XP IMM32 API Client DLL 82 ///模块名:LPK.DLL 版本:5.1.2600.5512 (xpsp.080413-2105) 描述:Language Pack 83 ///模块名:USP10.dll 版本:1.0420.2600.5969 (xpsp_sp3_gdr.100416-1716) 描述:Uniscribe Unicode script processor 84 ///模块名:comctl32.dll 版本:6.0 (xpsp_sp3_qfe.100823-1643) 描述:User Experience Controls Library 85 ///模块名:comctl32.dll 版本:5.82 (xpsp_sp3_qfe.100823-1643) 描述:Common Controls Library 86 ///模块名:rsaenh.dll 版本:5.1.2600.5507 (xpsp.080318-1711) 描述:Microsoft Enhanced Cryptographic Provider 87 ///模块名:xpsp2res.dll 版本:5.1.2600.5512 (xpsp.080413-2113) 描述:Service Pack 2 Messages 88 ///模块名:CLBCATQ.DLL 版本:2001.12.4414.700 描述: 89 ///模块名:COMRes.dll 版本:2001.12.4414.700 描述: 90 ///模块名:WINTRUST.dll 版本:5.131.2600.6285 (xpsp_sp3_gdr.120824-1617) 描述:Microsoft Trust Verification APIs 91 ///模块名:IMAGEHLP.dll 版本:5.1.2600.6198 (xpsp_sp3_gdr.120229-1643) 描述:Windows NT Image Helper 92 ///-------------------------------------------------------------------------- 93 static void Main(string[] args) 94 { 95 //4种常用的获取进程的方法 96 //1.获取本地计算机的所有进程 97 //Process[] myProcess=Process.GetProcesses(); 98 //2.获取本地计算机上指定名称的进程 99 //Process[] myProcess=Process.GetProcessesByName("进程名称"); 100 //3.获取远程计算机的所有进程(通过IP地址或计算机名称) 101 //Process[] myProcess=Process.GetProcesses("192.168.0.1"); 102 //或 Process[] myProcess=Process.GetProcesses("Server1"); 103 //4.获取远程计算机上指定名称的进程 104 //Process[] myProcess=Process.GetProcessesByName("Notpad","Server1"); 105 Process[] myProcess = Process.GetProcesses(); 106 foreach (Process p in myProcess) 107 { 108 Console.WriteLine("--------------------------------------------------------------------------"); 109 Console.WriteLine("p.Id:{0}", p.Id); 110 Console.WriteLine("p.ProcessName:{0}", p.ProcessName); 111 Console.WriteLine("p.WorkingSet64 / 1024.0f / 1024.0f:{0:###,##0.00}MB",p.WorkingSet64 / 1024.0f / 1024.0f); 112 Console.WriteLine("p.BasePriority:{0}",p.BasePriority); 113 Console.WriteLine("p.PagedSystemMemorySize64:{0}", p.PagedSystemMemorySize64); 114 Console.WriteLine("p.PagedMemorySize64:{0}", p.PagedMemorySize64); 115 //有些进程无法获取PriorityClass、UserProcessorTime、PrivilegedProcessorTime、TotalProcessorTime、StartTime、MainModule.FileName 116 try 117 { 118 Console.WriteLine("p.PriorityClass:{0}", p.PriorityClass); 119 } 120 catch 121 { 122 Console.WriteLine("p.PriorityClass:"); 123 } 124 try 125 { 126 Console.WriteLine("p.UserProcessorTime:{0}", p.UserProcessorTime); 127 } 128 catch 129 { 130 Console.WriteLine("p.UserProcessorTime:"); 131 } 132 try 133 { 134 Console.WriteLine("p.PrivilegedProcessorTime:{0}", p.PrivilegedProcessorTime); 135 } 136 catch 137 { 138 Console.WriteLine("p.PrivilegedProcessorTime:"); 139 } 140 try 141 { 142 Console.WriteLine("p.TotalProcessorTime:{0}", p.TotalProcessorTime); 143 } 144 catch 145 { 146 Console.WriteLine("p.TotalProcessorTime:"); 147 } 148 try 149 { 150 Console.WriteLine("p.StartTime:{0}", p.StartTime); 151 } 152 catch 153 { 154 Console.WriteLine("p.StartTime:"); 155 } 156 Console.WriteLine("-------------------------"); 157 try 158 { 159 //GetProcessById方法通过进程Id创建新的Process组件,并将其与本地计算机上的进程资源关联 160 //。在任何特定计算机上,进程的标识符都是唯一的。GetProcessById最多返回一个进程。要获取 161 //正在运行某特定应用程序的所有进程,应该使用GetProcessByName方法。如果运行指定应用程序 162 //的计算机上存在多个进程,则GetProcessesByName方法返回一个包含所有关联进程的数组,可以 163 //依次查询这些进程中的每一个标识符 164 ProcessModule m=Process.GetProcessById(p.Id).MainModule;//即p.MainModule 165 //使用MainModule查看文件名(带路径和扩展名)、版本、描述、语言等 166 Console.WriteLine("文件名:"+m.FileName); 167 Console.WriteLine("版本:"+m.FileVersionInfo.FileVersion); 168 Console.WriteLine("描述:"+m.FileVersionInfo.FileDescription); 169 Console.WriteLine("语言:"+m.FileVersionInfo.Language); 170 //使用Modules获取由关联进程加载的模块,即加载到特定进程中的.dll或.exe文件。 171 if (p.Modules != null) 172 { 173 ProcessModuleCollection pmc = p.Modules; 174 Console.WriteLine("调用的模块(.dll):"); 175 for (int i = 1; i < pmc.Count; i++) 176 { 177 Console.WriteLine("模块名:" + pmc[i].ModuleName + "\t版本:" + pmc[i].FileVersionInfo.FileVersion + "\t描述:" + pmc[i].FileVersionInfo.FileDescription); 178 } 179 } 180 } 181 catch 182 { 183 Console.WriteLine("其他信息:无法获取"); 184 } 185 } 186 Console.ReadKey(); 187 //Process类中的属性: 188 //名称 说明 189 //BasePriority 获取关联进程的基本优先级。 190 //Container 获取 IContainer,它包含 Component。(从 Component 继承。) 191 //EnableRaisingEvents 获取或设置在进程终止时是否应激发 Exited 事件。 192 //ExitCode 获取关联进程终止时指定的值。 193 //ExitTime 获取关联进程退出的时间。 194 //Handle 返回关联进程的本机句柄。 195 //HandleCount 获取由进程打开的句柄数。 196 //HasExited 获取指示关联进程是否已终止的值。 197 //Id 获取关联进程的唯一标识符。 198 //MachineName 获取关联进程正在其上运行的计算机的名称。 199 //MainModule 获取关联进程的主模块。 200 //MainWindowHandle 获取关联进程主窗口的窗口句柄。 201 //MainWindowTitle 获取进程的主窗口标题。 202 //MaxWorkingSet 获取或设置关联进程的允许的最大工作集大小。 203 //MinWorkingSet 获取或设置关联进程的允许的最小工作集大小。 204 //Modules 获取已由关联进程加载的模块。 205 //NonpagedSystemMemorySize 获取分配给此进程的未分页的系统内存大小。 206 //NonpagedSystemMemorySize64 获取为关联的进程分配的非分页系统内存量。 207 //PagedMemorySize 获取分页的内存大小。 208 //PagedMemorySize64 获取为关联的进程分配的分页内存量。 209 //PagedSystemMemorySize 获取分页的系统内存大小。 210 //PagedSystemMemorySize64 获取为关联的进程分配的可分页系统内存量。 211 //PeakPagedMemorySize 获取峰值分页内存大小。 212 //PeakPagedMemorySize64 获取关联的进程使用的虚拟内存分页文件中的最大内存量。 213 //PeakVirtualMemorySize 获取峰值虚拟内存大小。 214 //PeakVirtualMemorySize64 获取关联的进程使用的最大虚拟内存量。 215 //PeakWorkingSet 获取关联进程的峰值工作集大小。 216 //PeakWorkingSet64 获取关联的进程使用的最大物理内存量。 217 //PriorityBoostEnabled 获取或设置一个值,该值指示主窗口拥有焦点时是否由操作系统暂时提升关联进程的优先级。 218 //PriorityClass 获取或设置关联进程的总体优先级类别。 219 //PrivateMemorySize 获取专用内存大小。 220 //PrivateMemorySize64 获取为关联的进程分配的专用内存量。 221 //PrivilegedProcessorTime 获取此进程的特权处理器时间。 222 //ProcessName 获取该进程的名称。 223 //ProcessorAffinity 获取或设置可安排此进程中的线程在其上运行的处理器。 224 //Responding 获取指示进程的用户界面当前是否响应的值。 225 //SessionId 获取关联的进程的终端服务会话标识符。 226 //Site 获取或设置 Component 的 ISite。(从 Component 继承。) 227 //StandardError 获取用于读取应用程序错误输出的流。 228 //StandardInput 获取用于写入应用程序输入的流。 229 //StandardOutput 获取用于读取应用程序输出的流。 230 //StartInfo 获取或设置要传递给 Process 的 Start 方法的属性。 231 //StartTime 获取关联进程启动的时间。 232 //SynchronizingObject 获取或设置用于封送由于进程退出事件而发出的事件处理程序调用的对象。 233 //Threads 获取在关联进程中运行的一组线程。 234 //TotalProcessorTime 获取此进程的总的处理器时间。 235 //UserProcessorTime 获取此进程的用户处理器时间。 236 //VirtualMemorySize 获取进程的虚拟内存大小。 237 //VirtualMemorySize64 获取为关联的进程分配的虚拟内存量。 238 //WorkingSet 获取关联进程的物理内存使用情况。 239 //WorkingSet64 获取为关联的进程分配的物理内存量。 240 } 241 } 242 }
3. 启动停止进程
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Diagnostics; 6 using System.IO; 7 using System.Threading; 8 9 namespace test 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 //进程的启动 16 switch(2) 17 { 18 //根据文件名启动子进程,不等待子进程就结束 19 case 0: 20 Process.Start(@"C:\file1.txt"); 21 break; 22 //使用默认的浏览器打开URL 23 case 1: 24 string targetURL = @"http://www.baidu.com"; 25 Process.Start(targetURL); 26 break; 27 //根据应用程序名和参数启动子进程(类似控制台指令) 28 case 2: 29 //启动进程,首先需要创建一个Process组件的实例,并设置其对应的StartInfo 30 //属性,指定要运行的应用程序名称以及传递的参数,然后调用该实例的Start 31 //方法启动该进程。 32 // 33 //由于安装Windows操作系统后,Notepad.exe就已经安装到系统文件夹下,而且在任何一个 34 //文件夹中均可以直接运行,所以在这个例子中,我们选择了调用Notepad.exe作为演示的例子。 35 //实际上,可以通过这种方法调用任何一个可执行文件(.exe文件)或链接文件(如桌面快捷方式), 36 //并观察进程的执行效果。 37 string fileName="Notepad.exe";//或者@"C:\Program Files\Vim\vim73\gvim.exe" 38 //方法1: 39 ProcessStartInfo psi = new ProcessStartInfo(fileName, @"C:\file1.txt"); 40 //如果该进程带有图形用户界面,还可以指定图形用户界面打开的方式 41 //Normal:正常的可见窗口样式 42 //Hidden:隐藏窗口样式 43 //Minimized:最小化窗口样式 44 //Maximized:最大化窗口样式 45 psi.WindowStyle = ProcessWindowStyle.Maximized; 46 Process listFiles = Process.Start(psi); 47 //方法2: 48 //ProcessStartInfo psi = new ProcessStartInfo(fileName, @"C:\file1.txt"); 49 //psi.WindowStyle = ProcessWindowStyle.Hidden; 50 //Process listFiles = new Process(); 51 //listFiles.StartInfo = psi; 52 //listFiles.Start(); 53 //方法3: 54 //Process listFiles = new Process(); 55 //listFiles.StartInfo.FileName = fileName; 56 //listFiles.StartInfo.Arguments = @"C:\file1.txt"; 57 //listFiles.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 58 //listFiles.Start(); 59 //等待启动完成,否则获取进程信息可能会失败 60 //使Process组件等待关联进程进入空闲状态,仅适用于具有用户界面的进程。如果关联进程 61 //已经达到空闲状态,则返回true;否则返回false。此状态很有用,例如,应用程序需要 62 //等待启动的进程完成创建其主窗口,然后该应用程序才能与该窗口通信 63 listFiles.WaitForInputIdle(); 64 //获取启动进程的信息 65 ShowProcessInfo(fileName); 66 //等待5000毫秒后自动关闭 67 Thread.Sleep(5000); 68 //关闭进程 69 StopProcess(fileName); 70 //或者是使用关闭有图形界面的进程的方法,这时指定的值就是0 71 //StopProcessWin(fileName); 72 if (listFiles.HasExited) 73 { 74 //获取关联进程终止时指定的值。一般用为零的ExitCode值指示成功退出,并通过非零值指出错误 75 //,该值只能在HasExited属性为True时才能检测 76 Console.WriteLine("指定的值:{0}", listFiles.ExitCode); 77 //获取关联进程退出的时间,该值只能在HasExited属性为True时才能检测 78 Console.WriteLine("退出时间:{0}", listFiles.ExitTime); 79 Console.WriteLine("-----------------------------"); 80 } 81 ShowProcessInfo(fileName); 82 Console.ReadKey(); 83 break; 84 } 85 } 86 /// <summary> 87 /// 获取启动进程的信息 88 /// </summary> 89 /// <param name="fileName">文件名</param> 90 private static void ShowProcessInfo(string fileName) 91 { 92 //用GetFileNameWithoutExtension获得"gvim",供GetProcessesByName使用,获得一组process 93 Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(fileName)); 94 if (processes.Length > 0) 95 { 96 foreach (Process p in processes) 97 { 98 99 Console.WriteLine("进程ID:" + p.Id.ToString()); 100 Console.WriteLine("进程名称:" + p.ProcessName); 101 Console.WriteLine("占用内存:{0}KB", p.WorkingSet64 / 1024f); 102 Console.WriteLine("启动时间:{0}", p.StartTime); 103 Console.WriteLine("文件名:" + p.MainModule.FileName); 104 Console.WriteLine("-----------------------------"); 105 } 106 } 107 else 108 { 109 Console.WriteLine("无"); 110 Console.WriteLine("-----------------------------"); 111 } 112 } 113 //关闭进程 114 //可通过两种方法利用Process组件停止某进程。具体使用哪种方法取决于所停止的进程的类型。如果进程有 115 //图形用户界面,则调用其CloseMainWindow方法,该方法向进程的主窗口发送一个关闭请求,其行为与用户 116 //在界面中单击“关闭”按钮命令的效果相同。使用该方法使目标程序有机会在清除操作中提示用户保存任何 117 //没有保存的数据;如果进程没有用户界面,可以调用进程的Kill方法,该方法将在不提示保存已更改数据的 118 //情况下,立即停止进程,注意此时任何没有保存的数据都会丢失。 119 /// <summary> 120 /// 关闭进程,文件修改后,不提示关闭就退出 121 /// </summary> 122 /// <param name="fileName">文件名</param> 123 private static void StopProcess(string fileName) 124 { 125 Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(fileName)); 126 foreach (Process p in processes) 127 { 128 if (!p.HasExited) 129 { 130 //立即强制终止关联的进程。注意由于Kill方法是异步执行的,因此在调用Kill方法后,还要 131 //调用WaitForExit方法等待进程退出和检查HasExited属性以确定进程是否已经退出。对于有 132 //界面的应用程序,一般使用CloseMainWindow方法,而不是Kill方法,如果CloseMainWindow 133 //失败,则可以使用Kill方法终止进程。Kill方法是终止没有图形化界面的进程的唯一方法。 134 // 135 //如果在进程正要终止的同时调用了Kill方法,由于可能会因为访问被拒绝而引发Win32Exception 136 //异常,所以调用Kill方法时最好使用try/catch语句 137 p.Kill(); 138 //WaitForExit设置等待关联进程退出的时间,并在该段时间结束前或该进程退出前,阻止当前线程执行,很重要 139 p.WaitForExit(); 140 //释放与此组件关联的所有资源 141 p.Close(); 142 } 143 } 144 } 145 /// <summary> 146 /// 关闭有图形界面的进程,文件修改后,提示是否保存 147 /// </summary> 148 /// <param name="fileName">文件名</param> 149 private static void StopProcessWin(string fileName) 150 { 151 Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(fileName)); 152 foreach (Process p in processes) 153 { 154 if (!p.HasExited) 155 { 156 //kill方法用于强行终止进程,而CloseMainWindow只是“请求”终止进程。Kill方法会导致 157 //进程非正常终止,因而只在必要时才使用此方法。CloseMainWindow方法使进程能够有序终止 158 //并关闭所有窗口,所以对于有界面的应用程序,应该使用CloseMainWindow方法。如果调用 159 //CloseMainWindow方法失败,则可以使用Kill方法终止进程。 160 p.CloseMainWindow(); 161 p.WaitForExit(); 162 p.Close(); 163 } 164 } 165 } 166 } 167 }

浙公网安备 33010602011771号