我有一个窗口钩子,它监听正在创建的新窗口,并转发到执行一些自动化操作的.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.FromHandle
从句柄hwnd
中获取AutomationElement
。异常本身声明它已发生。
该异常是为了防止由于更改可视化树而导致的怪异而导致的可重入性错误,而这样的事件(本身已由可视化树更改触发)正在触发。
我正在寻找一种方法,当窗口准备好时,我可以调用这个函数,而不会在目标应用程序中导致这些异常。
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
本身。但是,不幸的是,我不得不依赖于钩子本身的事件。
https://stackoverflow.com/questions/49611816
复制相似问题