如何使 C# Com 对象 GlobalMultiUse?

Posted

技术标签:

【中文标题】如何使 C# Com 对象 GlobalMultiUse?【英文标题】:How to make C# Com object GlobalMultiUse? 【发布时间】:2018-10-14 22:39:45 【问题描述】:

我正在做一些 COM 互操作(VBA 客户端),并且有一个功能可能我认为是理所当然的,如果在 idl 中使用 idl 属性 appobject,则可以使用全局就绪实例化对象。这适用于 ATL/C++,因此我可以编写以下 IDL(ATL 项目)

[
    uuid(183343ca-6154-4c1e-9a6b-927e5b279332),
    version(1.0),
]
library GlobalCOMObjectLib

    importlib("stdole2.tlb");

    [
        odl,
        uuid(f1bd66ae-4fc9-45a4-8a2b-60df31d9bcfe),
        version(1.0),
        dual,
        oleautomation
    ]
    interface ISampleGlobalObject : IDispatch
    
        HRESULT Line([in]BSTR sIn, [out, retval] BSTR* outRetVal);
    ;

    [
        uuid(6a905a18-37d2-4ac1-a663-871f7dc99af7),
        version(1.0),
        appobject 
    ]
    coclass SampleGlobalObject
    
        [default] interface ISampleGlobalObject;
    ;
;

然后在 VBA 中我不需要新建 coclass 我可以编写以下内容

Sub TestGlobal3()
    Debug.Print SampleGlobalObject.Line("hello")
End Sub

如何在 C# 中做同样的事情,appobject 作为属性无法识别(波浪线)

namespace foo

    public interface ISampleGlobalObjectCSharp
    
        string Line(string sLine);
    

    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(ISampleGlobalObjectCSharp))]
    [appobject]
    public class SampleGlobalObject : ISampleGlobalObjectCSharp
    
        string ISampleGlobalObjectCSharp.Line(string sLine)
        
            return sLine;
        
    

在从 VB6 过渡到 C# 的时代,谷歌搜索会遇到页面,他们认为这是不可能的。 VB6 术语是GlobalMultiUse,如果这会触发任何记忆。

【问题讨论】:

那些页面是正确的。理想情况下,类型库导出器会关注 [TypeLibType] 属性,但它不会。并不是你不能得到它,而是它容易出错并且很难自动化。使用 Oleview.exe 反编译 .tlb 文件,文件 > 查看 TypeLib,复制/粘贴反编译的 idl 并在 [appobject] 属性中进行编辑,使用 midl.exe /tlb 重建 .tlb。 VBA 中的解决方法要容易得多。 Fwiw,GlobalMultiUse 是完全不同的东西,只影响进程外服务器使用的 REGCLS。 @HansPassant :是的,有效。干杯汉斯。 【参考方案1】:

将评论复制到答案以保留它:

那些页面是正确的。理想情况下,类型库导出器会支付 注意 [TypeLibType] 属性,但事实并非如此。它不像 你无法得到它,但它很容易出错并且很难自动化。 用 Oleview.exe 反编译 .tlb 文件,File > View TypeLib, 复制/粘贴反编译的 idl 并在 [appobject] 属性中进行编辑, 使用 midl.exe /tlb 重建 .tlb。 VBA 中的解决方法很多 更轻松。 Fwiw,GlobalMultiUse 是完全不同的东西, 仅影响进程外服务器使用的 REGCLS。

– Hans Passant 2018 年 5 月 4 日 13:05


OP 声明此评论是正确的。

【讨论】:

以上是关于如何使 C# Com 对象 GlobalMultiUse?的主要内容,如果未能解决你的问题,请参考以下文章

如何使相机跟随unity3d C#中的对象?

如何使用 C# 中的 System.Xml.Serialization 使对象不可变但可序列化?

从 C# 访问 COM 对象的最佳方法

使构造函数仅接受 C# 中具有 [Serializable] 属性的对象

如何使 .NET DLL 中的属性对 COM 可见(方法有效)

如何将 COM 对象的 C# 引用传递给 C++ DLL