Process.GetProcessesByName() 通过进程名(不含.exe后缀)匹配本机或远程计算机上同名进程,返回Process数组;需注意名称大小写、权限及跨会话限制。

Process.GetProcessesByName()是最直接的判断方式,但要注意它返回空数组 ≠ 进程没运行 —— 比如进程名带 `.exe` 后缀而你传的是无后缀名,就会查不到。
用 GetProcessesByName 判断进程是否存在
这个方法只匹配 ProcessName 字段(即不含路径、不含 `.exe` 的纯名称),所以传参必须严格对应。例如:notepad 可以匹配记事本,但 notepad.exe 会返回空数组。
- 正确写法:
Process.GetProcessesByName("chrome")→ 匹配所有 Chrome 浏览器进程 - 错误写法:
Process.GetProcessesByName("chrome.exe")→ 返回长度为 0 的数组 - 若不确定是否带后缀,建议先用
Process.GetProcesses()全量遍历 +string.Contains()或string.EndsWith(".exe")做模糊判断
CloseMainWindow 和 Kill 的区别与顺序
直接 Kill() 是暴力终止,不给程序保存或清理的机会;CloseMainWindow() 是发 WM_CLOSE 消息,模拟用户点关闭按钮 —— 大部分 GUI 程序会响应并正常退出。
- 优先调用
p.CloseMainWindow(),它返回bool:true 表示消息已发出,false 表示窗口不可见或无主窗口(比如后台服务) - 仅当
CloseMainWindow()返回 false 时,再调用p.Kill() - 注意:某些进程(如被调试、权限不足、已挂起)可能连
Kill()都抛出AccessDenied异常,需 try/catch
模糊匹配进程名时容易忽略的大小写和空格
ProcessName 在 Windows 上默认是小写(如 svchost),但有些进程启动时会保留原始大小写(如 OneDrive)。用 IndexOf 或 Contains 做模糊查找时,不加 StringComparison.OrdinalIgnoreCase 就可能漏掉。
- 安全写法:
p.ProcessName.IndexOf("onedrive", StringComparison.OrdinalIgnoreCase) >= 0 - 避免写法:
p.ProcessName.Contains("OneDrive")—— 在多数机器上会失败 - 额外注意:进程名里可能含空格或特殊字符(如
Microsoft Edge),建议用Trim()再比较
权限问题导致关闭失败的真实表现
非管理员权限下,Kill() 很可能抛出 System.ComponentModel.Win32Exception: 拒绝访问,而不是静默失败。尤其对系统级进程(svchost、lsass)或其它用户会话中的进程(如登录不同用户的 Chrome)。
- 检查当前程序是否以管理员身份运行:
WindowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator) - 跨会话进程无法通过
Process类直接操作,此时taskkill /F /FI "SESSION eq 1"也无效,必须用 WMI 或 Session 0 隔离方案 - 如果只是想“尽力关”,建议把
Kill()放在 try 块里,并记录失败 PID 和异常信息,方便后续排查
实际调用中,最易被忽略的是:进程名匹配逻辑和权限校验不是可选步骤,而是决定功能能否稳定工作的两个支点。漏掉任一环节,代码在测试机上跑通,上线后就可能大面积失效。











