【问题标题】:RegFree COM working from C#, NOT working from VBARegFree COM 从 C# 工作,而不是从 VBA 工作
【发布时间】:2012-04-06 00:11:11
【问题描述】:

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

显然,由于我使用的是 Excel,我不能简单地使用与可执行文件一起存在的客户端清单,所以我使用的是 Microsoft.Windows.ActCtx (link)

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

不幸的是,在 C# 中有效的东西似乎在 Excel / VBA 中无效,我对原因感到困惑。虽然 C# 测试客户端运行良好,但 VBA 给出了 80070002 错误,并显示消息 Method 'CreateObject' of object 'IActCtx' failed

我有一个 .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# 中创建对象,然后使用类似于 public object CreateObject(string manifestPath, string typeName) 的方法将其传递回现在,调用这从 C# exe 工作正常,但从 VBA 调用它失败(80070002 再次,消息:系统找不到指定的文件。)。现在我更迷茫了……

提前感谢您的帮助,如果我需要提供更多信息,请告诉我,我很乐意提供帮助!

【问题讨论】:

  • 你传递的Manifest路径无效,不能使用三个点。而且你肯定需要一个完整的路径,你无法预测当前的工作目录会是什么。
  • 抱歉混淆了,这只是一个占位符。路径是完整的,并且是正确的。

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


【解决方案1】:

使用进程监视器,我发现正在 C:/Program Files/Microsoft Office/Office11/ 中搜索 dll。我将所有的 dll 移到那里,错误就消失了。

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

【讨论】:

    【解决方案2】:

    我不能说我曾经尝试过使用这种技术,而且这些年来我已经完成了很多安装。我想知道,为什么不直接注册你的 .NET COM Visible 服务器呢? Regasm 倾向于在注册表中创建非常干净和轻量级的 COM 注册。比旧的非托管 DllRegisterServer() 的东西干净得多。

    【讨论】:

    • 不幸的是,这是在没有管理员权限的情况下部署的,所以 regasm 是不可能的......
    • InstallShield MSI 项目具有“.NET COM Visible”属性,该属性在构建时调用 RegAsm 以提取 COM 元数据。在按用户安装的情况下,COM 密钥被写入 HKCU\Software\Classes 而不是 HKLM\Software\Classes。我不明白 RegAsm 风格的 COM 注册是怎么回事。
    猜你喜欢
    • 2017-06-26
    • 2011-02-11
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2022-09-29
    • 1970-01-01
    相关资源
    最近更新 更多