Generating your own interop dll for calling the Windows UIA API from C# code
I was recently asked where an interop dll can be found, so that an app’s C# code can call into the Windows UIA API. Whenever I'm working on a new app which leverages the awesome power of UIA, I always generate the interop dll myself. (Or I could root around my machine looking for an interop dll that I've generated in the past.) I've always found it quick 'n' easy to generate the interop dll once I got familiar with the steps. I could update the build steps for my project in Visual Studio to have the dll generated as part of the project build, but in my case, I only ever need the interop dll to be generated once, so I don't tend to do that.
The interop dll contains the metadata required for the calls from C# into the unmanaged Windows UIA API. Once I've generated the interop dll, I can view the object types from within Visual Studio's Object Browser while I'm working on my C# code. I can also view the contents using the ILDASM tool if I wanted to, as shown below.
Figure 1: ILDASM tool showing the contents of my UIA interop dll.
Anyway, below describes how I generate and work with the dll. Hopefully these steps will work for you too.
Guy
Whenever I’m working on a project where I’m calling the Windows UIA API from C# code, I use an interop dll that I’ve generated myself using a tool call tlbimp.exe. This might not produce exactly the same interface as the one exposed by the interop dll referenced in some older MSDN blog posts, but the results will be similar, and I always find it useful to be able to generate my own interop dll whenever I want.
So first I find where the tlbimp.exe tool is on my computer, by doing cd “C:\Program Files (x86)\Microsoft SDKs” in a command window, and then dir /s tlbimp.exe. Depending on the versions of the Windows developer tools I have, I may have different versions of tlbimp.exe. Once I’ve found the most current version I have, I use it to generate a UIA interop dll. For example, I might run this:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\x64\TlbImp.exe" C:\Windows\System32\UIAutomationCore.dll -out:interop.UIAutomationCore.dll
When I do that, I get lots of warnings, but I still get the interop.UIAutomationCore.dll generated that I need. I can then go to my C# project in Visual Studio, and add a reference to my interop dll in my project’s list of references.
Figure 2: A reference to my UIA interop dll in the project's list of references.
I can then use the VS Object Browser to see all the classes available through the interop dll.
Figure 3: Using the Visual Studio Object Browser to view the object types available through the interop dll.
I can add “using interop.UIAutomationCore;” to the top of my C# file and start creating and using objects through the interop dll. For example:
CUIAutomation8 automation = newCUIAutomation8();
IUIAutomationElement element = automation.GetFocusedElement();
string focusedElementName = element.CurrentName;
Comments
Anonymous
April 10, 2015
Guy, Thanks for this! I just had an odd thing happen with the interop dll I have been using ever since we corresponded way back. My development machine is windows 7, 64 bit. I tlbimport'ed the core file there. I wanted use MTM to run my compiled assembly (with the 64 bit interop dll) on a 32 bit VIrtual Machine (VMware). I am unable to ".GetRootElement" Do I have to import a 32 bit and a 64 bit version? Thanks, PeterAnonymous
April 11, 2015
Hi Peter, as far as I know, you'll need to use a version of tlbimp.exe that matches the bitness of the client app that you're calling it from. If you've been running everything 64-bit up to now, but are now also setting things up to run on 32-bit, your client process will need to be 32-bit. Hopefully it's not too much additional work to incorporate the interop dlls built with the 32-bit and 64-bit tmbimp.exes into your build/setup processes. As I look at my 64-bit machine now, I see six tlbimp.exes beneath "C:Program Files (x86)Microsoft SDKsWindows" on my machine. There are two each beneath V7.0A, V8.0A and V8.1A folders. Of these, I'm only ever interested in the V8.1A versions. For each version, there’s a tmpimb.exe in a bin folder, and another in a binx64 folder. You could incorporate the building of the interop dlls with these two versions into the building of your project, or build the two interop dlls beforehand, and have the appropriate one picked up during project build and setup. Not that I've done that, but it sounds fairly doable... Thanks, GuyAnonymous
April 11, 2015
Wouldn't you know it, I'm probably completely wrong in my earlier comment. Those different versions of tlbimp.exe will relate to the bitness of the machine that you're running them on, not the bitness associated with the interop dll. MSDN says at msdn.microsoft.com/.../tt0cf3sx(v=vs.100).aspx, that you can run tlbimp.exe with the /machine:x86 option to generate the 32-bit interop dll. So hopefully through a mix of the versions of tlbimp.exe and use of the /machine option, you can get the interop dlls you need. Sorry for the confusion. My use of tlbimp has be somewhat limited, even though it's been essential to me in building various assistive technology tools. GuyAnonymous
December 14, 2015
Guy, is there a place where I can look at examples of using the Windows UIA? I would like to switch to the .NET UIA as it doesn't seem to be able to access Edge. I followed your instructions and now have an interop, but I am looking for "FromPoint" if that is possible.Anonymous
December 14, 2015
Guy, I figured out how to get the element from point, but I'm not sure how to get the list of patterns, or how to access the textpattern.