Предупреждение MSB3391: <DLL> не содержит типов, которые могут быть не зарегистрированы для COM-взаимодействия

Я сделал простую C# DLL (это часть гораздо большего проекта) с использованием VS2005. Мне нужно использовать DLL в Excel через код VBA, поэтому я использую COM Interop на сборке. Я пытаюсь заставить процесс сборки автоматически генерировать необходимый файл TLB, чтобы мне не нужно было переходить в командную строку и использовать regasm после каждой сборки.

Моя проблема в том, что, хотя DLL компилируется и собирается нормально, она не генерирует файл TLB. Вместо этого ошибка в заголовке выводится в поле вывода.

Я получил другие библиотеки DLL для создания файлов TLB, перейдя в свойства проекта в VS2005 -> Build -> Output -> Check "Регистрация для взаимодействия COM". Также у меня есть [assembly: ComVisible(true)] в AssemblyInfo.cs.

Вот краткая информация об источнике для проблемной 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*/
    }
}

3 ответа

Решение
  1. Вам нужно иметь ctor без каких-либо параметров.
  2. Вы должны иметь GuidAttribute и ProgIdAttribute вокруг классов.
  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()
        {
        }
    }
    

В файле 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)]

ОБНОВИТЬ:

Читайте: Как я могу использовать объекты.NET из Excel VBA?

Которые ссылаются на: http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/

Я видел похожую проблему. Я получил ошибку вроде:

предупреждение MSB3391: не содержит типов, которые могут быть не зарегистрированы для COM Interop.

Я следовал всем правилам (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 Framework может быть какая-то разница - возможно, более поздняя версия слишком оптимизирует, и REGASM не учитывает это.

Другие вопросы по тегам