предупреждение MSB3391:<DLL> не содержит никаких типов, которые могут быть незарегистрированы для COM-взаимодействия
-
21-08-2019 - |
Вопрос
Я создал простую C # DLL (это часть гораздо более крупного проекта), используя VS2005.Мне нужно использовать DLL в Excel через код VBA, поэтому я использую COM-взаимодействие в сборке.Я такой и есть попытка заставить процесс сборки автоматически генерировать необходимый файл TLB так что мне не нужно заходить в командную строку и использовать regasm после каждой сборки.
Моя проблема в том, что, хотя библиотека DLL компилируется и собирается нормально, она не генерирует файл TLB.Вместо этого ошибка в заголовке выводится в поле вывода.
Я получил другие библиотеки DLL для сборки файлов TLB, перейдя в свойства проекта в VS2005 -> Build -> Output -> Check "Зарегистрироваться для COM-взаимодействия".Кроме того, у меня есть [сборка: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*/
}
}
Решение
- Вам нужно иметь ctor без каких-либо параметров.
- Тебе следовало бы Направляющий атрибут и Прогидаттрибут по классам.
- Лучше пометить сборку как 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() { } }
Другие советы
Я видел аналогичную проблему.Я получил ошибку типа:
предупреждение MSB3391:не содержит никаких типов, которые могут быть незарегистрированы для Com Interop.
Я выполнил все правила (ComVisible и т. д.), но ничего не помогло.
Решение: Мне пришлось что-то поместить в конструктор по умолчанию, чтобы его нельзя было оптимизировать.В тот момент, когда у меня что-то было, регистрация завершилась без сообщения, и компонент стал виден в реестре.
Интересное замечание: моему другу удалось зарегистрировать исходную DLL с пустым конструктором по умолчанию на своей машине (64-битная Windows-7, VS2008-Professional, как у меня).Однако его REGASM.EXE был:
C:\Windows\Microsoft.NET\Framework64\v2.0.50727 egasm.exe
а у меня было:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319 egAsm.exe
Таким образом, между версиями .NET Framework может быть некоторая разница - возможно, более поздняя версия слишком сильно оптимизируется, и REGASM это не учитывает.
Убедитесь, что в файле 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/