warning MSB3391: <DLL> does not contain any types that can be unregistered for COM Interop

你。 提交于 2019-12-19 05:22:08

问题


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 file so that I don't need to go to the command line and use regasm after every build.

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.

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.

Here's the summary of the source for the problem DLL and the DLL that it references for a return type:

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.

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*/
    }
}

回答1:


  1. You need to have ctor without any params.
  2. You should have GuidAttribute and ProgIdAttribute around the classes.
  3. Its better to mark the assembly as ComVisible(false) and mark explicitly the classes that need export.
  4. Use interfaces for your classes.
  5. 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()
        {
        }
    }
    



回答2:


I saw a similar problem. I got an error like:

warning MSB3391: does not contain any types that can be unregistered for COM Interop.

I followed all the rules (ComVisible, etc.) but nothing worked.

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:

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

while mine was:

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.




回答3:


In the AssemblyInfo.cs file, make sure you have the following:

// 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/



来源:https://stackoverflow.com/questions/853553/warning-msb3391-dll-does-not-contain-any-types-that-can-be-unregistered-for-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!