当我们启动一个程序,用 Process process = Process.Start(path);//path是程序的绝对路径
启动时,获取的process.Handle其实是进程的句柄,并不是窗口的句柄,而有时process.MainWindowHandle却等于0
此时就需要用枚举来获取启动进程的主窗口句柄了,代码如下
////// 用于枚举子窗体是的委托 /// /// 窗体句柄 /// 自定义 ///public delegate bool EnumChildWindow(IntPtr WindowHandle, string num); /// /// 获取指定窗体的所有子窗体 /// /// 窗体句柄 /// 回调委托 /// 自定义 ///[DllImport("User32.dll")] public static extern int EnumChildWindows(IntPtr WinHandle, EnumChildWindow ecw, string name); /// /// 获取指定窗体的标题 /// /// 窗体句柄 /// 缓冲区取用于存储标题 /// 缓冲区大小 ///[DllImport("User32.dll")] public static extern int GetWindowText(IntPtr WinHandle, StringBuilder Title, int size); /// /// 获取窗体类型 /// /// 窗体句柄 /// 类型 /// 缓冲区大小 ///[DllImport("user32.dll")] public static extern int GetClassName(IntPtr WinHandle, StringBuilder Type, int size); /// /// 根据句柄获得进程id值 /// /// 句柄 /// ///[DllImport("user32")] private static extern int GetWindowThreadProcessId(IntPtr handle, out int pid); IntPtr mainHwnd = IntPtr.Zero;//登录窗口句柄string typeName = string.Empty;//启动程序的窗口标题 /// /// 枚举窗体 /// /// /// ///private bool EnumChild(IntPtr handle, string num) { StringBuilder title = new StringBuilder(); //StringBuilder type = new StringBuilder(); title.Length = 100; //type.Length = 100; GetWindowText(handle, title, 100);//取标题 //GetClassName(handle, type, 100);//取类型 if (title.ToString() == typeName) { mainHwnd = handle; return false; } return true; }//代码调用pubilc boolTest(){ FileVersionInfo myFileVersion = FileVersionInfo.GetVersionInfo(path); typeName = myFileVersion.ProductName;//获取程序产品名称int waitTime = 0; while (true) { EnumChildWindow ecw = new EnumChildWindow(EnumChild); EnumChildWindows(mainWindowHandle, ecw, ""); GetWindowRect(mainHwnd.ToInt32(), ref rectMain); int pid = 0; GetWindowThreadProcessId(mainHwnd, out pid); //rectMain.Height - rectMain.Y < 300说明是登录窗口 if (mainHwnd != IntPtr.Zero && process.Id == pid && rectMain.Height - rectMain.Y < 300)//276 break; waitTime++; //30秒没打开程序,登录失败 if (waitTime >= 30) return false; Thread.Sleep(1000); }return true;}