11

我使用 VS2005 制作了一个简单的 C# DLL(这是一个更大项目的一部分)。我需要通过 VBA 代码在 Excel 中使用 DLL,因此我在程序集上使用 COM Interop。我正在尝试使构建过程自动生成必要的 TLB 文件,这样我就不需要在每次构建后转到命令行并使用 regasm。

我的问题是,虽然 DLL 编译和构建很好,但它不会生成 TLB 文件。相反,标题中的错误会在输出框中打印出来。

通过转到 VS2005 -> Build -> Output -> Check "Register for COM interop"中的项目属性,我已经获得了其他 DLL 来构建 TLB 文件。我还在AssemblyInfo.cs 中有[assembly: ComVisible(true)] 。

以下是问题 DLL 的源代码以及它为返回类型引用的 DLL 的摘要:

using System;
using System.IO;
using System.Runtime.InteropServices;
using SymbolTable;

namespace ProblemLibrary
{
    public class Foo
    {    
        public Foo(string filename)
        {
            ...
        }

        // method to read a text file into a SymbolTable
        public SymbolTable BuildDataSet(string[] selected)
        {
            ...
        }
    }
}

这里是 SymbolTable.dll 的摘要。它拥有 ProblemLibrary 使用的返回类型。

using System;
using System.Collections.Generic;

namespace SymbolTable
{
    public class SymbolTable
    {
        readonly Dictionary<SymbolInfoStub, string> _symbols = new Dictionary<SymbolInfoStub, string>();

       /*methods that interact with Dictionary snipped*/
    }
}
4

3 回答 3

24
  1. 你需要有没有任何参数的ctor。
  2. 您应该在类周围有GuidAttributeProgIdAttribute
  3. 最好将程序集标记为 ComVisible(false) 并明确标记需要导出的类。
  4. 为您的类使用接口。
  5. 确保您在程序集级别中有 GuidAttribute。

    [Guid("<PUT-GUID-HERE-1>")]
    [ComVisible(true)]
    interface IFoo
    {
        void DoFoo();
    }
    
    [Guid("<PUT-GUID-HERE-2>")]
    [ComVisible(true)]
    [ProgId("ProgId.Foo")]
    class Foo : IFoo
    {
        public void DoFoo()
        {
        }
    }
    
于 2009-05-12T19:10:33.850 回答
4

在 AssemblyInfo.cs 文件中,确保您具有以下内容:

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]

更新:

阅读:如何在 Excel VBA 中使用 .NET 对象?

链接到: http ://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/

于 2009-05-12T18:43:00.960 回答
3

我看到了类似的问题。我收到如下错误:

警告 MSB3391:不包含任何可以为 COM 互操作取消注册的类型。

我遵守了所有规则(ComVisible 等),但没有任何效果。

解决方案:我必须在默认构造函数中放入一些东西,这样它就不会被优化掉。当我有东西的那一刻,注册完成,没有任何消息,并且该组件在注册表中可见。

有趣的注释:我的一个朋友设法在他的机器上注册了原始的 DLL 空的默认构造函数(64 位 Windows-7,VS2008-Professional,就像我的一样)。然而,他的 REGASM.EXE 是:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm.exe

而我的是:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe

因此,.NET 框架的版本之间可能存在一些差异——也许更高版本的优化太多,而 REGASM 没有考虑到这一点。

于 2011-03-02T23:28:28.837 回答