question

LarsLarsson-8935 avatar image
1 Vote"
LarsLarsson-8935 asked llarsson commented

WinForms / WPF - MS.Win32.UnsafeNativeMethods.GetWindowText

Seeing a looping of throws System.ComponentModel.Win32Exception.
Can see it using ProcesExplorer or enable native & disable "just my code" - otherwise it goes by "undetected"

How does one troubleshoot it - quite complex application with WinForms & WPF (ElementHost), have not touched any AutomationPeer occurs in different parts of code usually during visibility toggle (i.e. false) or close. But how to root cause it. Once it triggers it keeps retriggering i.e. App.Run seeing thrown C# exception increase all the time.


 System.ComponentModel.Win32Exception
   HResult=0x80004005
   Message=Invalid window handle
   Source=WindowsBase
   StackTrace:
    at MS.Win32.UnsafeNativeMethods.GetWindowText(HandleRef hWnd, StringBuilder lpString, Int32 nMaxCount)
    
   This exception was originally thrown at this call stack:
     MS.Win32.UnsafeNativeMethods.GetWindowText(System.Runtime.InteropServices.HandleRef, System.Text.StringBuilder, int)

Target framework 4.8 but some might be older, plugin based and got history back from .NET 1.0 but don't think its related.

windows-wpfwindows-forms
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I have the same issue, running a WinForms app (framework 4.7.1) with WPF content. We are more ppl woring on this, and so far, it only happens to me, which is even weirder, and just like you, the error message is useless. Checking the box to catch Win32Exceptions in VS doesnt help, it is unrecoverable and no other information that is relevant is given. It happens randomly, but, as you say, usually in conjunction with opening a Dialog popup or overlay.

0 Votes 0 ·
LarsLarsson-8935 avatar image
1 Vote"
LarsLarsson-8935 answered llarsson commented

I can get it in the debugger and reproduce it but I cannot retrive any valuable information / make sense of it. My guess is its related to ElementHost or at least google returns those that use ElementHost or UI libraries where they overriden AutomationPeer related.

But looking for known issues / or any good way to actually get out more information or if this is "normal" operation.

Sample call stack

 ot Flagged    >    22080    1    Worker Thread    Main UI 1    WindowsBase.dll!MS.Win32.UnsafeNativeMethods.GetWindowText
                               WindowsBase.dll!MS.Win32.UnsafeNativeMethods.GetWindowText(System.Runtime.InteropServices.HandleRef hWnd, System.Text.StringBuilder lpString, int nMaxCount)
                               PresentationCore.dll!System.Windows.Automation.Peers.GenericRootAutomationPeer.GetNameCore()
                               PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
                               PresentationCore.dll!System.Windows.ContextLayoutManager.fireAutomationEvents()
                               PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout()
                               PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayoutCallback(object arg)
                               PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
                               PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object resizedCompositionTarget)
                               PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget)
                               WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
                               WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler)
                               WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl()
                               WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj)
                               mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
                               mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
                               mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
                               WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
                               WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke()
                               WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue()
                               WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
                               WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
                               WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)
                               WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
                               WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler)
                               WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)
                               WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam)
                               [Native to Managed Transition]
                               user32.dll!00007ffa3ea0e858()
                               user32.dll!00007ffa3ea0e299()
                               System.Windows.Forms.ni.dll!00007ffa060eb6d9()
                               [Managed to Native Transition]
                               System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData)
                               System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context)
                               System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context)
                               MyProgream.Program.Main() Line 196
                               [Native to Managed Transition]
                               mscoreei.dll!00007ffa19ef8c01()
                               mscoree.dll!00007ffa19fdac42()
                               kernel32.dll!00007ffa3f2b7034()
                               ntdll.dll!00007ffa3f4a2651()
· 10
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

You seem to have a Winforms window. It is getting a message to be processed. That triggers a call into the WPF host. While trying to get the name of the control in question from accessibility it is throwing an exception which is ultimately what you see fail. In my experience accessibility is finicky so this may just be expected as it is being handled.

If you are responsible for the Automation calls then note that the built in automation libraries in the framework are old and are targeting the old automation objects. There is no MS-provided newer library but you can get third party code that uses the newer and more reliable automation code which seems to work better for the few times I've tried to use it.

Alternatively you can look at other approaches to getting the automation data. There are a couple of different approaches available and in my limited testing when I needed it different UIs work better with different windows but I don't know why.

1 Vote 1 ·

Haven't done anything in particular regarding accessibility or external tooling. I think of it as a simple WinForms -> ElementHost -> WPF UserControls (with many children thou).
If it would occur once I would also deem it like a normal but looking in ProcessExplorer or visual studio console it spamms once it starts.

Is there anything special one must do regarding ElementHost or somehow narrow that stack down to elementHost A & reason B. I kind of know one view that only had one host that caused issue but seems like "hello world" kind of thing that just should work alt. what am I missing i.e. you must always do X.

1 Vote 1 ·

If you're running in the debugger then you can figure it out. When the exception is thrown you'll have the call stack available. In the Call Stack window you can click each frame and see the local variables. For instance methods the this pointer will be there which will tell you what object triggered it. Assuming the exception is coming from something you created you'll be able to see enough info to map it to your code. You also have the HWND so using that you could use Spy++ or equivalent to find that HWND in your running code to figure out which window.

Looking at the stack trace I can see that a media object was in the mix and it triggered a content layout rendering which ultimately causes the exception so another place to narrow things down is where you might be using media and a content layout. That resizeCompositionTarget argument is probably something that can be looked at to figure things out as well.

If none of that is working then you might just need to slow remove UI elements temporarily until the problem goes away, or start with a base UI and slowly add your components back until the problem replicates.

0 Votes 0 ·
Show more comments

Did you manage to resolve this, or get any closer to a resolution?

The problem with Win32Exception is "new" to this app; I have been upgrading it to use async/await and this problem started occurring in the process of the refactoring/upgrade. There is a version of this app that is not using TPL, and that older version still is a WInForms app with WPF controls on it, and I have never seen this issue then.

So, I am considering if the incremental introduction of TPL is causing the issue. I am on Win10; others are on Win11 and never see the problem...

0 Votes 0 ·

No I did not look into it - wanted to thou but to me it is catched in underlaying code so does not cause any obvious errors.

Also sometimes at least earlier I got issues with early versions of visual studio attaching its debug panel to runtime window but was fixed long time ago also, but reminder that other things can potentially be cause.

0 Votes 0 ·
cooldadtx avatar image
0 Votes"
cooldadtx answered Mikael-8137 commented

In the debugger go to the exception settings. Find the Win32Exception and tell the debugger to break when it is thrown. Then run your app. As soon as anybody throws the exception the debugger will break in.

The actual problem is that somebody is trying to get the window text from a bad window handle. Nevertheless it is very common to have thrown exceptions. You generally won't see them because somebody handles them. By setting the debugger to break on throw you'll see them all, which could be too much.

The other scenario is that it could be thrown on a secondary thread and the thread is terminated. Normally this will crash your app as defined here. But you mentioned 1.0 so I'll say that in that release unhandled exceptions are silently handled as discussed in the link already given. However you wouldn't be hosting a 1.x assembly in a .NET 4 app so this shouldn't be an issue.

Outside the debugger option mentioned earlier, if the exception is being handled by somebody else there isn't a good way to track it as you won't get notified, because it is already handled.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Checking Win32exp in the Exception options does not give any new or more information, the error message is still the same and doesnt help really to resolve the issue.

Thanks for input into what may be the reason for this. In my case, I get the error message, but 2 others does not. They are on Win11, I am on Win10. This app, however, is a work-in-progress, an upgrader from a previous version, and in this newer version, we are migrating over to using TPL (async/await) on the client side, which in the older version was not used. I am suspecting that this has something to do with that...

0 Votes 0 ·