C# 通过进程名/进程Id 操作窗口/程序
1. 判断窗口是否存在
1 private bool IsWindowExist(IntPtr handle) 2 { 3 return (!(GetWindow(new HandleRef(this, handle), 4) != IntPtr.Zero) && IsWindowVisible(new HandleRef(this, handle))); 4 } 5 6 [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 7 public static extern IntPtr GetWindow(HandleRef hWnd, int uCmd); 8 9 [DllImport("user32.dll", CharSet = CharSet.Auto)] 10 public static extern bool IsWindowVisible(HandleRef hWnd);
2. 获取窗口句柄
1 /// <summary> 2 /// 获取应用程序窗口句柄 3 /// </summary> 4 /// <param name="processId"></param> 5 /// <returns></returns> 6 private IntPtr GetWindowHandle(int processId) 7 { 8 var windowHandle = IntPtr.Zero; 9 EnumThreadWindowsCallback windowsCallback = new EnumThreadWindowsCallback(FindMainWindow); 10 EnumWindows(windowsCallback, IntPtr.Zero); 11 //保持循环 12 GC.KeepAlive(windowsCallback); 13 14 bool FindMainWindow(IntPtr handle, IntPtr extraParameter) 15 { 16 int num; 17 GetWindowThreadProcessId(new HandleRef(this, handle), out num); 18 if (num == processId && IsWindowExist(handle)) 19 { 20 windowHandle = handle; 21 return true; 22 } 23 return false; 24 } 25 26 return windowHandle; 27 } 28 public delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam); 29 30 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 31 public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData); 32 33 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 34 public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);
3. 关闭应用窗口
根据进程Id关闭应用窗口:
1 /// <summary> 2 /// 关闭程序主窗口 3 /// </summary> 4 /// <param name="processId">进程ID</param> 5 public void CloseWindow(int processId) 6 { 7 var mwh = GetWindowHandle(processId); 8 SendMessage(mwh, MW_CLOSE, 0, 0); 9 } 10 const int MW_CLOSE = 0x0010; 11 12 [DllImport("User32.dll", EntryPoint = "SendMessage")] 13 private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
关闭所有此进程名的窗口:
1 public void CloseAllWindows(string processName) 2 { 3 Process[] processList = Process.GetProcessesByName(processName); 4 foreach (Process process in processList) 5 { 6 CloseMainWindow(process.Id); 7 } 8 }
当然,直接杀进程,是最快的方法:
1 /// <summary> 2 /// 关闭所有进程 3 /// </summary> 4 /// <param name="processName"></param> 5 /// <returns></returns> 6 public static bool CloseAllProcesses(string processName) 7 { 8 try 9 { 10 Process[] psEaiNotes = Process.GetProcessesByName(processName); 11 foreach (Process psEaiNote in psEaiNotes) 12 { 13 psEaiNote.Kill(); 14 } 15 } 16 catch 17 { 18 return false; 19 } 20 21 return true; 22 }
4. 重启程序
1 string appFileName = currentClientProcess.MainModule.FileName; 2 3 Process newClient = new Process(); 4 newClient.StartInfo.FileName = appFileName; 5 // 设置要启动的进程的初始目录 6 newClient.StartInfo.WorkingDirectory = System.Windows.Forms.Application.ExecutablePath; 7 8 //启动程序 9 currentClientProcess.Kill(); 10 newClient.Start();
窗口之间发送/接收消息的处理,请参考《C# 跨进程通信》
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)