我正在尝试使用Excel作为客户端的无注册的COM,并将.NET dll作为服务器.目前我只是想得到一个概念验证工作,但是遇到麻烦.
显然,由于我正在使用Excel,我不能简单地使用与可执行文件一起使用的客户端清单,所以我使用的是Microsoft.Windows.ActCtx(link)
我有客户端清单,汇编清单和dll都在同一个位置.
不幸的是,C#中的工作似乎在Excel / VBA中不起作用,我被遗漏了.虽然C#测试客户端工作得很好,VBA给出了一个80link2错误,而对象“IActCtx”的消息方法“CreateObject”失败.
我有一个.NET DLL(COMTestService.dll)将单个类/接口暴露给COM(COMTestObject / ICOMTestObject),如下所示:
[ComVisible(true),InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] [Guid("EEE50CDF-D8EC-4F38-B986-C231EC45171E")] public interface ICOMTestObject { [ComVisible(true)] string GetString(int number); } [ComVisible(true),ClassInterfaceAttribute(ClassInterfaceType.None),ComDefaultInterface(typeof(ICOMTestObject))] [Guid("6E54611B-8B56-49E0-9415-E59B0774A4BE")] public class COMTestObject : ICOMTestObject { public COMTestObject() { } public string GetString(int number) { return string.Format("The number is: {0}",number); } }
客户端清单(COMTestService_Client.manifest):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" > <assemblyIdentity name="client" version="1.0.0.0" /> <dependency> <dependentAssembly> <assemblyIdentity name="COMTestService" version="1.0.0.0" processorArchitecture="msil" /> </dependentAssembly> </dependency> </assembly>
汇编清单(COMTestService.manifest):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" > <assemblyIdentity name="COMTestService" version="1.0.0.0" processorArchitecture="msil" /> <clrClass clsid="{6E54611B-8B56-49E0-9415-E59B0774A4BE}" progid="COMTestService.COMTestObject" threadingModel="Both" name="COMTestService.COMTestObject" runtimeVersion="v4.0.30319"> </clrClass> <file name="COMTestService.dll" hashalg="SHA1"> </file> </assembly>
VBA客户端代码:
Dim actCtx As Object Set actCtx = CreateObject("Microsoft.Windows.ActCtx") actCtx.Manifest = "...\COMTestService_Client.manifest" Dim testObject As Object Set testObject = actCtx.CreateObject("COMTestService.COMTestObject") 'This line throws... Dim text As String text = thing.GetString(42) Debug.Print text
C#客户端代码:
var actCtxType = System.Type.GetTypeFromProgID("Microsoft.Windows.ActCtx"); dynamic actCtx = System.Activator.CreateInstance(actCtxType); actCtx.Manifest = @"...\COMTestService_Client.manifest"; var type = System.Type.GetTypeFromProgID("COMTestService.COMTestObject"); dynamic obj = System.Activator.CreateInstance(type); dynamic s = obj.GetString(42);
编辑
剧情变厚…只是为了好玩,我写了一个快速COM可见的REGISTERED助手类来做C#中的对象创建,然后传回它,使用沿公共对象CreateObject(string manifestPath,string typeName )现在,从C#exe调用这个可以正常工作,但是从VBA调用它失败(80link2再次,消息:系统找不到指定的文件).现在我更加困惑…
提前感谢任何帮助,如果我需要提供任何更多的信息,让我知道,我会很高兴有义务!