I’m working on an application that monitors what’s running on a windows machine. It will be used to raise alarms if certain dialogs pop up during automated processes. I’m using the windows API to get the class name of existing windows, which works fine. However, if these are .NET applications, then rather than the .NET class name, I get something like ‘WindowsForms10.Window.8.app.0.39cfeeb’, and to make matters worse, the class name is not constant between executions.
Is there a way to get the .NET class name when only presented with a windows handle?
Yes, this can’t work. Every unique window in a desktop session must have a unique Windows “class name”, the string passed to the RegisterClassEx() winapi function and used in CreateWindowEx(). Winforms auto-generates those names so it has the burden to ensure that the names it generates don’t collide with names of windows in other processes and appdomains. Which is why you see these bizarro names, the most important part is the last bit, 39cfeeb in your example, the value returned by AppDomain.GetHashCode(). You cannot retrieve that hash code from an external process.
You’ll need a fundamentally different approach that doesn’t rely on the easily obtainable class name. Look at the Managed Spy code, it supports using Reflection on an external Winforms process. Isolating the DLL injection code technique it uses so you can use this yourself in your own code takes some work.
Also the only way you’ll ever get the .NET class name out of the process, something you otherwise never really care about when using UI automation.