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# 跨进程通信》
作者:唐宋元明清2188
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。