我有一个Windows挂钩,可以监听正在创建的新窗口并转发到执行某些自动化的.NET模块。
问题是当启动的应用程序很少时,调用AutomationElement.FromHandle(hwnd)
时,应用程序崩溃System.InvalidOperationException
Application: Ssms.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException
Stack:
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
发生崩溃时我正在进行的唯一操作是尝试使用AutomationElement
从句柄hwnd
获取AutomationElement.FromHandle
。
异常本身表明它发生
异常是为了防止由于引起的重入错误而完成的 改变视觉树所产生的怪异,同时也是这样的事件 (它本身是由视觉树改变引发的)是 烧成。
我正在寻找一种方法,可以在窗口准备就绪时调用此函数,并且不会在目标应用程序中导致这些异常。
try{
AutomationElement temp = AutomationElement.FromHandle(hwnd);
LogMessage("Found Element from HWND " + hwnd.ToString("x") + "(" + hwnd + ")");
return Pool.Add(temp, msg);
}
catch (System.Exception ex){
LogMessage("Exception while element from HWND " + hwnd.ToString("x") + "(" + hwnd + ")");
}
有没有办法可以检测目标窗口是否准备就绪然后调用我的函数?到目前为止,我发现这项工作的唯一方法是使用
Thread.Sleep(3000);
但是,并不总能保证它会起作用,在某些情况下等待时间可能太长。
我知道听UIAutomation Events
可以解决这个问题,因为事件会在回调中给AutomationElement
本身。但是,不幸的是,我不得不依赖钩子本身的事件。