Sunday, March 1, 2009

Retrieving information from an external application: Part 1

Good evening,

Have you ever been in a situation where your application had to communicate with a 3rd party application that you obviously don't have the source code for?  In my situation, I have to be able to retrieve information out of the client's internal application that they themselves didn't write.  We can't ask them to modify their application to give us the information we need to be able to provide them with the needed information from our .NET application.  What to do then?  This is what the IT world calls "cross process" or "remote process" communications.  What are our options?  After some research and common consensus  among my co-workers, we decided to use Desaware's SpyWorks for the solution.

In a nutshell, SpyWorks is a set of libraries that work in one of the basic level of the operating system and with some API calls to the correct methods, we are able to retrieve said information from 3rd party applications.

What is my objective in this situation?  To retrieve information from multiple types of controls in the client's application.  These components are single-line text boxes, multi-line text boxes, rich text boxes, labels, combo boxes, list views, list boxes and tree views to start with.  Overall, I want to be able to retrieve the information, and in the case of multiple choices, the user selected item in the 3rd party application.

To be able to test my code, we'll have to create a test application with all said controls on it.  A simple form with 1 control of each type will suffice.  One more control will be added to the bottom of the form, and that will be a label that will indicate the selected control's "handle".  More on this later.  Here's what the form will look like:


As you can see, I have all the different kinds of controls that I'm looking to retrieve information from.  They are all populated with data and represent a good test form for our purpose.  The only code in this form is for the Click event of each control.  All these event methods do are to put the selected control's handle in the label at the bottom of the dummy app's form.  The following image represents the code behind the DummyApp form:


Now let's look at the application that will be retrieving the information.  It will need a way to indicate which control we want to retrieve the information from, a button to start the retrieval and a textbox of some kind to display the information that was retrieved.  Here's what this form looks like:


As you can see, it's a very simple form with various buttons.  I'll go into details further down, but simple to say that each button allows you to capture information out of a specific type of control, 7 control types to be exact.  The sample applications are written in C# for .NET 2.0 using Visual Studio 2005 Professional.  It is good to know that each control has it's own way of storing it's information in memory, hence the different buttons.  It would have been too easy if Microsoft had made it that all controls' information could be retrieved the same way.

How do you find out which API method you need to call with which parameters to obtain the information you want?  Well, to be completely honest, I don't know if there's a good place to find all the needed information.  I did my research using Google's search engine and with lots of tries, time and patience, I found the necessary information.  Not all of it was readily available, but with some persistence and some trial and error, I was able to make each control retrieval work.  Make no mistake, I'm not a master of the Windows APIs in any way, shape or form, but after this project, I do know that much more about it then when I started.

Each API method requires a parameter called "handle" that points to the control that you're trying to retrieve information from.  That's what that label at the bottom of the dummy application is for.  When you click on a control, the label will display that selected control's handle for you to use in your calling application.  In the real world, 3rd party applications will not provide you this information and you'll have to use applications like Spy++ (distributed with Visual Studio) or write one yourself to find this information out.  The details on how to write your own application to find 3rd party control handles will be for another time and another article.  For now, all you need to know is that the dummy application provides you this information in the bottom label and you need to enter this number into the testing application's top text box and then click on the appropriate button to be able to retrieve the information from that control.

In part 2 of this article, we'll dig into the testing application where all the code and API calls to retrieve the selected control's information is located.

Until next time,

Sebastien Limoges