C# 警告 MSB3391:<DLL> 不包含任何可以为 COM Interop 取消注册的类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/853553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
warning MSB3391: <DLL> does not contain any types that can be unregistered for COM Interop
提问by
I've made a simple C# DLL (that's part of a much larger project) using VS2005. I need to use the DLL in Excel via VBA code so I am using COM Interop on the assembly. I am trying to make the build process automatically generate the necessary TLB fileso that I don't need to go to the command line and use regasm after every build.
我使用 VS2005 制作了一个简单的 C# DLL(这是一个更大项目的一部分)。我需要通过 VBA 代码在 Excel 中使用 DLL,所以我在程序集上使用 COM Interop。我试图让构建过程自动生成必要的 TLB 文件,这样我就不需要在每次构建后进入命令行并使用 regasm。
My problem is that although the DLL compiles and builds fine, it does not generate a TLB file. Instead, the error in the title prints out in the output box.
我的问题是,虽然 DLL 编译和构建良好,但它不会生成 TLB 文件。相反,标题中的错误会打印在输出框中。
I've gotten other DLLs to build TLB files by going to the project's properties in VS2005 -> Build -> Output -> Check "Register for COM interop". Also I have [assembly: ComVisible(true)] in the AssemblyInfo.cs.
通过在 VS2005 -> Build -> Output -> Check "Register for COM interop" 中转到项目的属性,我已经获得了其他 DLL 来构建 TLB 文件。我也在AssemblyInfo.cs 中有[assembly: ComVisible(true)]。
Here's the summary of the source for the problem DLL and the DLL that it references for a return type:
以下是问题 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)
{
...
}
}
}
Here is a summary of SymbolTable.dll. It holds a return type that ProblemLibrary uses.
下面是 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*/
}
}
采纳答案by Shay Erlichmen
- You need to have ctor without any params.
- You should have GuidAttributeand ProgIdAttributearound the classes.
- Its better to mark the assembly as ComVisible(false) and mark explicitly the classes that need export.
- Use interfaces for your classes.
Make sure the you have GuidAttribute in the assembly level.
[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() { } }
- 你需要有没有任何参数的ctor。
- 你应该在类周围有GuidAttribute和ProgIdAttribute。
- 最好将程序集标记为 ComVisible(false) 并明确标记需要导出的类。
- 为您的类使用接口。
确保您在程序集级别具有 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() { } }
回答by NotMe
In the AssemblyInfo.cs file, make sure you have the following:
在 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)]
UPDATE:
更新:
Read: How can I make use of .NET objects from within Excel VBA?
Which links to: http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/
链接到:http: //richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/
回答by Dror Harari
I saw a similar problem. I got an error like:
我看到了类似的问题。我收到一个错误,如:
warning MSB3391: does not contain any types that can be unregistered for COM Interop.
警告 MSB3391:不包含任何可以为 COM Interop 取消注册的类型。
I followed all the rules (ComVisible, etc.) but nothing worked.
我遵循了所有规则(ComVisible 等),但没有任何效果。
Solution:I had to put something in the default constructor so that it would not be optimized away. The moment I had something there, the registration finished with no message and the component was visible in the registry.
解决方案:我不得不在默认构造函数中放一些东西,这样它就不会被优化掉。当我在那里有东西的那一刻,注册完成,没有消息,组件在注册表中可见。
Interesting note:a friend of mine managed to register the original DLL with the empty default constructor on his machine (64-bit Windows-7, VS2008-Professional, like mine). However, his REGASM.EXE was:
有趣的提示:我的一个朋友设法在他的机器(64 位 Windows-7,VS2008-Professional,就像我的)上用空的默认构造函数注册了原始 DLL。但是,他的 REGASM.EXE 是:
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm.exe
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm.exe
while mine was:
而我的是:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe
So it could be some difference between versions of the .NET framework - maybe the later version is optimizing too much and the REGASM does not account for that.
因此,.NET 框架的版本之间可能存在一些差异 - 也许更高版本的优化太多而 REGASM 没有考虑到这一点。