Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В этой статье пошагово объясняется, как сделать класс доступным для COM из .NET Core (или .NET 5+). В этом учебнике описаны следующие процедуры.
- Объявление класса для COM из .NET Core.
- Создайте сервер COM в процессе сборки библиотеки .NET Core.
- Автоматически создавайте параллельный манифест сервера для технологии Registry-Free COM.
Предварительные условия
- Установите пакет SDK для .NET Core 3.0 или более новой версии.
Создание библиотеки
Сначала нужно создать библиотеку.
Создайте новую папку и в этой папке выполните следующую команду.
dotnet new classlibОткрыть
Class1.cs.Добавьте
using System.Runtime.InteropServices;в начало файла.Создайте интерфейс с именем
IServer. Например:using System; using System.Runtime.InteropServices; [ComVisible(true)] [Guid(ContractGuids.ServerInterface)] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IServer { /// <summary> /// Compute the value of the constant Pi. /// </summary> double ComputePi(); }Добавьте в интерфейс атрибут
[Guid("<IID>")]с идентификатором GUID реализуемого интерфейса COM. Например,[Guid("fe103d6e-e71b-414c-80bf-982f18f6c1c7")]. Обратите внимание, что этот идентификатор GUID должен быть уникальным, так как он является единственным идентификатором данного интерфейса для модели COM. В Visual Studio можно создать GUID, перейдя в раздел "Сервис > создания GUID", чтобы открыть средство создания GUID.Добавьте в интерфейс атрибут
[InterfaceType]и укажите, какие базовые COM-интерфейсы должен реализовывать ваш интерфейс.Создайте класс
Server, реализующийIServer.Добавьте в класс атрибут
[Guid("<CLSID>")]с идентификатором GUID реализуемого класса COM. Например,[Guid("9f35b6f5-2c05-4e7f-93aa-ee087f6e7ab6")]. Как и в случае с GUID интерфейса, этот GUID должен быть уникальным, так как он является единственным идентификатором данного интерфейса в COM.Добавьте атрибут
[ComVisible(true)]как в интерфейс, так и в класс.
Внимание
В отличие от .NET Framework, .NET Core обязывает указать идентификатор CLSID для любого класса, который должен активироваться с помощью COM.
Создание узла COM
- Откройте файл проекта
.csprojи добавьте элемент<EnableComHosting>true</EnableComHosting>внутри тега<PropertyGroup></PropertyGroup>. - Выполните сборку проекта.
В результате будут получены файлы ProjectName.dll, ProjectName.deps.json, ProjectName.runtimeconfig.json и ProjectName.comhost.dll.
Регистрация хоста COM для COM
Откройте командную строку с повышенными привилегиями и запустите regsvr32 ProjectName.comhost.dll. Это приведет к регистрации всех открытых объектов .NET в COM.
Если вы планируете внедрить библиотеку типов (TLB), рекомендуется также определить функции с помощью ComRegisterFunctionAttribute и ComUnregisterFunctionAttribute. Эти функции можно использовать для регистрации и отмены регистрации TLB для COM-сервера. Полный пример см. в OutOfProcCOM примере.
Включение поддержки RegFree COM
- Откройте файл проекта
.csprojи добавьте элемент<EnableRegFreeCom>true</EnableRegFreeCom>внутри тега<PropertyGroup></PropertyGroup>. - Выполните сборку проекта.
В результате будет также получен файл ProjectName.X.manifest. Это параллельный манифест для использования с моделью COM без поддержки реестра.
Внедрение библиотек типов на узле COM
В отличие от .NET Framework, в .NET Core и .NET 5 или более поздней версии создание библиотеки типов COM (TLB) из сборки .NET не поддерживается. Нужно вручную написать файл IDL или заголовок C/C++ для собственных объявлений COM-интерфейсов. Если вы решили написать файл IDL, его можно скомпилировать с помощью компилятора MIDL пакета SDK Visual C++, чтобы создать TLB-файл.
В .NET 6 и более поздних версиях пакет SDK для .NET поддерживает внедрение уже скомпилированных TLB-файлов на узле COM в рамках сборки проекта.
Чтобы внедрить библиотеку типов в приложение, выполните следующие действия.
- Откройте файл проекта
.csprojи добавьте элемент<ComHostTypeLibrary Include="path/to/typelib.tlb" Id="<id>" />внутри тега<ItemGroup></ItemGroup>. - Замените
<id>на положительное целое значение. Чтобы внедрение на узле COM было возможным, значение должно быть уникальным для указанных TLB-файлов.- Атрибут
Idявляется необязательным, если в проект добавляется только один объектComHostTypeLibrary.
- Атрибут
Например, следующий блок кода добавляет типовую библиотеку Server.tlb с индексом 1 в хост COM.
<ItemGroup>
<ComHostTypeLibrary Include="Server.tlb" Id="1" />
</ItemGroup>
Загрузка по умолчанию AssemblyLoadContext
Во время активации сборка, содержащая компонент модели COM, загружается отдельно по пути к сборке AssemblyLoadContext. Если имеется одна сборка, предоставляющая несколько серверов модели COM, компонент AssemblyLoadContext используется повторно, поскольку все серверы из этой сборки находятся в одном контексте загрузки. Если существует несколько сборок, предоставляющих серверы COM, для каждой сборки создается новый AssemblyLoadContext, и каждый сервер находится в контексте загрузки, соответствующем этой сборке.
В .NET 8 и более поздних версиях сборка может указать, что она должна быть загружена по умолчанию AssemblyLoadContext. Чтобы включить загрузку в контексте по умолчанию, добавьте в проект следующий элемент RuntimeHostConfigurationOption :
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Runtime.InteropServices.COM.LoadComponentInDefaultContext" Value="true" />
</ItemGroup>
Пример
В репозитории dotnet/samples на сайте GitHub есть полнофункциональный пример сервера COM.
Дополнительные примечания
Внимание
В .NET Framework сборка "Any CPU" может использоваться и с 32-разрядными, и с 64-разрядными клиентами. По умолчанию в .NET Core, .NET 5 и более поздних версиях сборки "Любой ЦП" сопровождаются 64-разрядным *.comhost.dll. По этой причине они могут использоваться только в 64-разрядных клиентах. Это настроено по умолчанию, поскольку это то, что предоставляет пакет SDK. Такое поведение аналогично публикации "автономного" компонента: по умолчанию он использует то, что предоставляет пакет SDK. Свойство NETCoreSdkRuntimeIdentifier MSBuild определяет битность *.comhost.dll. Управляемая часть на самом деле не зависит от ожидаемой разрядности, однако разрядность сопутствующего ресурса по умолчанию совпадает с разрядностью целевого пакета SDK.
Автономные развертывания COM-компонентов не поддерживаются. Поддерживаются только зависящие от платформы развертывания COM-компонентов.
Представление COM-компонентов из проектов C++/CLI через свойство EnableComHosting не поддерживается.
Кроме того, загрузка как .NET Framework, так и .NET Core в один и тот же процесс имеет ограничения диагностического характера. Основное ограничение — отладка управляемых компонентов, так как невозможно одновременно выполнить отладку .NET Framework и .NET Core. Кроме того, два экземпляра среды выполнения не используют управляемые сборки совместно. Это означает, что невозможно совместно использовать фактические типы .NET в двух средах выполнения, вместо этого все взаимодействия должны быть ограничены предоставленными контрактами COM-интерфейса.