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

Я сделал простую 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 ]

21 голосов
/ 12 мая 2009
  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()
        {
        }
    }
    
3 голосов
/ 03 марта 2011

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

предупреждение 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 не учитывает это.

1 голос
/ 12 мая 2009

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

Чтение: Как использовать объекты .NET из Excel VBA?

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

...