如何使 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?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 中的 System.Xml.Serialization 使对象不可变但可序列化?
使构造函数仅接受 C# 中具有 [Serializable] 属性的对象