Предупреждение 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 ответа
- Вам нужно иметь 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() { } }
В файле 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 не учитывает это.