C#检测外部exe程序弹窗错误,并重启
//可以放到timer里执行
private void button2_Click(object sender, EventArgs e) { string mainTitle = System.Configuration.ConfigurationManager.AppSettings["mainTitle"]; //弹框的class名称可以用Spy++程序来获取 string mainClassName = System.Configuration.ConfigurationManager.AppSettings["mainClassName"]; string labelClassName = System.Configuration.ConfigurationManager.AppSettings["labelClassName"]; string buttonTxt = System.Configuration.ConfigurationManager.AppSettings["buttonTxt"]; //MessageBox弹框 var isFind = FindException(mainTitle, mainClassName, labelClassName, buttonTxt); if (isFind == false) { var list = System.Diagnostics.Process.GetProcessesByName("Win.Process"); var sb1 = new StringBuilder(100); foreach (var item in list) { GetClassNameW(item.MainWindowHandle, sb1, sb1.Capacity); sb1.Append(","); } string dynamicName = sb1.ToString().Split('.').Last().Replace(",", ""); mainClassName = "WindowsForms10.Window.8.app.0." + dynamicName; labelClassName = "WindowsForms10.STATIC.app.0." + dynamicName; buttonTxt = "退出(&Q)"; //未捕获异常弹窗 FindException(mainTitle, mainClassName, labelClassName, buttonTxt); } }
/// <summary> /// 获取报错弹窗,记录日志,然后重启目标程序 /// </summary> /// <param name="mainTitle"></param> /// <param name="mainClassName"></param> /// <param name="labelClassName"></param> /// <param name="buttonTxt"></param> /// <returns></returns> private bool FindException(string mainTitle, string mainClassName, string labelClassName, string buttonTxt) { appWin = FindWindow(mainClassName, mainTitle); if (appWin != IntPtr.Zero) { IntPtr childHwnd = FindWindowEx(appWin, IntPtr.Zero, null, buttonTxt); if (childHwnd != IntPtr.Zero) { var sb = new StringBuilder(500); var label = FindWindowEx(appWin, IntPtr.Zero, labelClassName, null); if (label != IntPtr.Zero) { GetWindowText(label, sb, sb.Capacity); var log = $"\n{DateTime.Now}\n获取的异常:{ sb.ToString()}\n"; richTextBox1.AppendText(log); richTextBox1.ScrollToCaret(); System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory +"/"+ DateTime.Now.ToString("yyyyMMdd")+ ".txt", log); //SendEmail( $"【{mainTitle}】出现异常:{sb.ToString()}"); } SendMessage(childHwnd, BM_CLICK, 0, 0); SendMessage(childHwnd, BM_CLICK, 0, 0); System.Threading.Thread.Sleep(1000);
//重启程序 System.Diagnostics.Process.Start(_targetExePath); } return true; } return false; }
[DllImport("user32.dll", EntryPoint = "SendMessageA")] private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam); //窗口发送给按钮控件的消息,让按钮执行点击操作,可以模拟按钮点击 private const int BM_CLICK = 0xF5; [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int nMaxCount); [DllImport("user32.dll", EntryPoint = "FindWindowEx")] private extern static IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); //获取窗口类名 [DllImport("user32.dll")] private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <appSettings> <add key="mainTitle" value="xxx系统"/> <add key="mainClassName" value="#32770"/> <add key="labelClassName" value="Static"/> <add key="buttonTxt" value="确定"/> <add key="targetExePath" value="D:\xxx.exe"/> </appSettings> </configuration>
/*
文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放 文字少不能投放
*/