RegFree COM来自C#,不在VBA工作

时间:2012-03-21 13:05:34

标签: .net vba com side-by-side regfreecom

我正在尝试使用Excel作为客户端和.NET dll作为服务器来使用免注册COM。目前我只是试图让概念验证工作,但我遇到了麻烦。

显然,当我使用Excel时,我不能简单地使用与可执行文件一起生成的客户端清单,因此我使用Microsoft.Windows.ActCtxlink

我将客户端清单,程序集清单和dll都放在同一位置。

不幸的是,在C#中工作的东西似乎在Excel / VBA中不起作用,我很难理解。虽然C#测试客户端工作正常,但VBA发出 80070002 错误,消息对象'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可见,注册助手类来在C#中创建对象,然后使用public object CreateObject(string manifestPath, string typeName)的方法将其传回去,从C#exe调用它可以正常工作,但从VBA调用它失败(再次80070002,消息:系统找不到指定的文件。)。现在我更加困惑......

预先感谢您提供任何帮助,如果我需要提供更多信息,请告诉我,我很乐意帮忙!

2 个答案:

答案 0 :(得分:2)

使用Process Monitor,我发现在C:/ Program Files / Microsoft Office / Office11 /中搜索了dll。我将所有的dll移到那里,错误消失了。

在旁注中,如果有人知道如何告诉Excel不要查看我的文件,而是找到.tlb的地方,我很感兴趣。 (我已经尝试添加路径到PATH环境变量)

答案 1 :(得分:0)

我不能说我曾尝试使用这种技术,多年来我已经做了很多安装。我不禁要问,为什么不注册.NET COM Visible服务器? Regasm倾向于在注册表中创建非常干净和轻量级的COM注册。比旧的非托管DllRegisterServer()更清洁。