简体   繁体   English

将类公开为STA COM

[英]Expose a class as STA COM

I have a little c# class that I need to expose as COM. 我有一个小c#类,我需要公开为COM。 THe tool that will use the COM object requires that I support STA. 使用COM对象的工具要求我支持STA。 Is there anything special that I need to do with my COM object? 我的COM对象需要做些什么特别的事吗?

(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). (我知道STAThread属性,但是(除非我错了)它用于指示.net中的执行线程是STA兼容的,而不是用于指示我的COM对象需要兼容)。

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 {..}

A COM server advertises the threading model it requires with a registry entry named ThreadingModel. COM服务器使用名为ThreadingModel的注册表项通告所需的线程模型。 Single threaded is the default if the registry key is missing or when it is set to "Apartment". 如果缺少注册表项或将其设置为“Apartment”,则单线程是默认值。

Regasm.exe sets this key to "Both". Regasm.exe将此键设置为“Both”。 Which means that your server is declared to be compatible with both STA threads and MTA threads. 这意味着您的服务器被声明为与STA线程和MTA线程兼容。 Somewhat in keeping with .NET code in general, it supports threading but with the requirement that you have to take care of thread-safety. 有点与.NET代码保持一致,它支持线程,但要求你必须处理线程安全。 Changing this is very awkward, you have to write your own registration procedure and annotate it with the [ComRegisterFunction] attribute. 更改它非常尴尬,您必须编写自己的注册过程并使用[ComRegisterFunction]属性对其进行注释。

The simple approach is leave the key set to "Both" and to check the apartment state in your class constructor. 简单的方法是将键设置为“Both”并检查类构造函数中的单元状态。 Use Thread.GetCurrentThread().GetApartmentState(). 使用Thread.GetCurrentThread()。GetApartmentState()。 If you get MTA then throw an exception to tell the client that you don't support multi-threading. 如果您获得MTA,则抛出异常以告知客户端您不支持多线程。 Lots of .NET classes do this. 很多.NET类都这样做。

See this answer for an example of a ComRegisterFunction that does the necessary registry voodoo. 有关执行必要注册表巫毒的ComRegisterFunction的示例,请参阅此答案 There are a few cases where you might want this - eg when you want to ensure that your threads are STA so you can interact with other COM objects that require use only by STA threads. 在某些情况下,您可能需要这样 - 例如,当您想确保您的线程是STA时,您可以与需要仅由STA线程使用的其他COM对象进行交互。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM