Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expose a class as STA COM

Tags:

c#

.net

com

I have a little c# class that I need to expose as COM. THe tool that will use the COM object requires that I support STA. Is there anything special that I need to do with my COM object?

(I know about the STAThread attribute, but (unless I'm wrong) It is for indicating that a thread of execution in .net is to be STA compatible, and not for indicating that my COM object needs to be compatible).

Here's my declaration so far. Do you see anything that I need to add?


    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(ITestClass1))]
    [Guid("093A3701-2C53-4A31-97C5-0F3C205E5B4C")]
    public class Class1: ITestClass1 {..}

    [ComVisible(true)]
    [Guid("8D52F785-CDD8-4248-8AB7-97B8C19DE59B")]
    public interface ITestClass1 {..}

like image 222
JMarsch Avatar asked Jan 22 '23 17:01

JMarsch


1 Answers

A COM server advertises the threading model it requires with a registry entry named ThreadingModel. Single threaded is the default if the registry key is missing or when it is set to "Apartment".

Regasm.exe sets this key to "Both". Which means that your server is declared to be compatible with both STA threads and MTA threads. Somewhat in keeping with .NET code in general, it supports threading but with the requirement that you have to take care of thread-safety. Changing this is very awkward, you have to write your own registration procedure and annotate it with the [ComRegisterFunction] attribute.

The simple approach is leave the key set to "Both" and to check the apartment state in your class constructor. Use Thread.GetCurrentThread().GetApartmentState(). If you get MTA then throw an exception to tell the client that you don't support multi-threading. Lots of .NET classes do this.

like image 55
Hans Passant Avatar answered Feb 01 '23 05:02

Hans Passant