As a start to the next 2 years of blogging I want to look back on an “ancient” technology : COM, which is still the glue between software parts created with a great diversity of tools. COM brought me to .NET, exploring the world of COM in Delphi I discovered the .NET 1.0 betas. Never to leave again.
COM support in .NET is good. You can make your .NET code accessible to any COM client (for instance VBscript) by setting the “Register for COM Interop” property in a project.
Having done that all the public classes in your assembly are available as COM server classes. Public methods and properties are exposed as COM callable methods and props. You can finetune this by setting the ComVisible attribute on a class or method
public class MyComClass
public void MyNonComMethod()
This makes building COM servers with .NET a snap.
But there is one huge drawback: you can register only a dll for COM interop. And not an exe like a WinForms application. Making a Winforms application (COM) automatable requires a little work on the architecture of your app.
- Creat a windows forms application
- Add a class library to the solution
- Add System.Windows.Forms to the references of the lib
- Add a form to the class library
- Add the classlibrary to the references of the winforms app
- Delete the main form of the windows app
- Add a new class to the winform application
Your solution should now look like this
By deleting the mainform from the windows app we have also removed the entry point of the application. By default on startup a .net executable searches for a static main method. VS generates this method for you in the mainform. The new entry point will now be in the MainClass.
public class MainClass
static void Main()
It does exactly the same as the original main method, but it creates a form which is housed in the class library instead of the exe itself. Now you still have your winform app and have moved all “real” code into a class library.
The next step is to make the application automatable. Add a new class libary to the solution and register it for COM interop. The library references the windows form class library and System.Windows.Forms. The Show method of the COM class will fire up the mainform found in the MyWinFormClassLibrary. Just creating the form and running it, like the Main method did, has one problem: the method will not return to the calling COM client untill the application has stopped running the mainform. That is when the winform app has terminated. To circumvent this the form has to be started in a separate thread. Given the great threading support in .NET this no big deal either.
public class MyComClass
private void formThread()
public void Show()
Thread t = new Thread(new ThreadStart(formThread));
t.ApartmentState = ApartmentState.STA;
The actual code to run the mainform is in the private formThread method. Which is wrapped up in a ThreadStart delegate. A more detailed article on threading in winforms is here.
This snippet of VBscript will test your code
set o = CreateObject(“MyWinComServer.Test”)
msgBox(“Click to stop”)
It creates the mainform. You can toy around with that until you click the script-messagebox. Which will terminate your main app.
As the thread in the server interacts with the UI you have to set the thread’s appartmentstate to STA. Another thing to watch out for is when you want to access the form from other methods in your COM class. You will cross a thread boundary and have to Invoke methods and properties on the form. More details are in this article.
That should do the trick. Of a very great value was this blogpost by Rick Strahl on automating winforms in general. This result is just a couple of lines code but .NET is doing some very powerfull things here. More than enough to get you into trouble, so feel free to chime in.