Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
COM — это технология Windows для определения и работы с объектами и типами, которые могут использоваться различными клиентскими приложениями на платформе Windows. См. раздел "Объектная модель компонента" (COM).
Вы можете ссылаться на COM-компонент в проекте .NET, в этом случае он должен быть проецирован в управляемой сборке, называемой основной сборкой взаимодействия или PIA. Сборка взаимодействия содержит управляемые типы, соответствующие типам объектов COM (как представлено интерфейсами, описанными в библиотеках типов) и перенаправляет вызовы API в COM. Для получения общих сведений о COM-взаимодействии см. раздел COM Interop.
Вы можете ссылаться на com-компоненты в проектах .NET Framework или в проектах .NET Core (включая .NET 5 или более поздней версии). Visual Studio предоставляет способы добавления ссылок на COM-объекты. Например, COM-компонент, который является элементом пользовательского интерфейса Windows (элементом ActiveX), может быть представлен на Панели инструментов, а при перетаскивании его в форму Windows или форму Windows Presentation Foundation (WPF) добавляется в качестве COMReference в файле проекта.
Вы также можете добавить ссылки COM непосредственно в обозревателе решений. Щелкните правой кнопкой мыши на Зависимости и выберите "Добавить COM-ссылку".
MSBuild может создавать сборки-оболочки для COM-ссылок. Во время сборки ResolveComReference задача выполняется и использует системный реестр для поиска всех ссылочных COM-объектов, создает оболочки путем вызова tlbimp.exeи записывает его на диск в папку проекта.
Далее в этой статье показаны различные способы ссылки на com-компоненты и некоторые возможные ошибки, которые могут возникать при использовании каждого метода.
COMReference
Тип COMReference элемента ссылается на com-компонент с помощью системного реестра. GUID и версия — это первичные ключи, используемые для поиска компонента.
<ItemGroup>
<COMReference Include="MyComLibrary">
<Guid>{01234567-89AB-CDEF-0123-456789ABCDEF}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
</COMReference>
</ItemGroup>
</Project>
Так как используется системный реестр, компоненты должны быть зарегистрированы на компьютере сборки. Это лучше всего подходит, если вы собираете только из Visual Studio на локальном компьютере, где вы управляете установленным программным обеспечением и у вас могут быть права администратора для изменения реестра. Однако при сборке на сервере или в контейнере, например в сценариях CI/CD, необходимо убедиться, что на сервере сборки установлены правильные продукты, а также изменения на сервере, такие как установка новой версии Office или удаление пакета программного обеспечения, могут привести к нарушению сборки. Или хуже, не нарушая сборку, но ссылаясь на другую версию того же компонента, чем та, для которой был написан ваш код.
Другая проблема заключается в том, что com-компонент, полученный из реестра, может иметь некоторые незначительные отличия от компонента, для который был написан код. Он зависит от издателя компонента и установки каких-либо обновлений, которые его изменили, не изменяя номера версий. Этот тип несовместимости не приведет к ошибке сборки, но может привести к ошибке во время выполнения, если изменения были достаточно значительными, чтобы нарушить то, от чего зависит ваше приложение.
Общие сведения о том, как COM-компоненты представлены в разделе реестра, можно найти в разделе Регистрация COM-приложений.
COMFileReference
Тип COMFileReference элемента ссылается на COM-компоненты по пути к файлу. Реестр не используется во время сборки. Это важная альтернатива COMReference , если вы не хотите, чтобы процесс сборки зависел от системного реестра. Если вы используете COMFileReference, вам не нужно беспокоиться о том, как зарегистрировать com-компоненты, необходимые приложению, пока приложение не будет установлено и запущено на компьютере пользователя, что является большим преимуществом, так как процесс сборки может выполняться без повышенных привилегий, необходимых для записи в реестр.
<ItemGroup>
<COMFileReference Include="Controls\MyCom32.dll" />
</ItemGroup>
Чтобы полностью избежать записи в реестр, используйте COM без регистрации с манифестом.
Может возникнуть проблема с компонентом, который может отличаться от того, для которого вы писали код, если указанный путь не находится под вашим контролем. Если пакет программного обеспечения обновляет компонент на компьютере сборки без обновления сведений о версии, возможно, вы загружаете другой компонент с потенциальной несовместимостью. Чтобы избежать этого, можно использовать кэшированную, известную версию двоичных файлов COM и ссылаться только на нее.
Reference
Это рекомендуемый способ ссылаться на COM-компоненты с новыми версиями .NET. Сборки-оболочки предварительно создаются, а не создаются на каждом сеансе сборки, а выходные данные ссылаются непосредственно как на управляемые сборки.
Иногда сборки-оболочки (PIA) распределяются поставщиком COM-компонентов. Если это так, вы можете ссылаться на них непосредственно как на управляемые сборки. Это не отличается от ссылки на любую другую сборку .NET, за исключением того, что во время выполнения существует зависимость от устанавливаемого и зарегистрированного com-компонента.
Чтобы создать сборки-оболочки самостоятельно для com-компонентов, которые вы хотите использовать, используйте tlbimp.exe или aximp.exe для элементов ActiveX.
Используя этот метод, можно избежать необходимости повышения привилегий для записи в системный реестр во время сборки. Если вы создаете собственные сборки-оболочки и храните их в месте, которое вы управляете, возможно, в пакете NuGet или в папке, доступной для вашего решения, вы можете быть изолированы от изменений, которые находятся за пределами вашего контроля.
Bitness
Если ваш проект ссылается на 32-разрядные компоненты COM, вы должны собирать с использованием MSBuild.exe или Visual Studio, а не dotnet build. Это связано с тем, что dotnet build выполняет 64-разрядную версию MSBuild, которая не может работать с 32-разрядными компонентами COM.
COM-компоненты однажды были все скомпилированы в 32-разрядные двоичные файлы. Позже, когда появилась 64-разрядная технология, стало возможным скомпилировать COM-компонент как в 32-разрядные, так и 64-разрядные двоичные файлы. Один и тот же компонент часто доступен в 32-разрядных и 64-разрядных двоичных файлах. В таких случаях идентификаторы GUID или CLSID, которые определяют уникальный компонент, одинаковы для 32-разрядных и 64-разрядных двоичных файлов, но сам реестр разделяется на 32-разрядные и 64-разрядные разделы.
Ошибки могут возникнуть, если проекты настроены неправильно для ссылки на правильный бит компонента COM, который вам нужен. Если компонент COM доступен только в виде 32-разрядного двоичного файла, приложение может использовать его только в том случае, если он выполняется как 32-разрядный процесс. Если сборка .NET создается как 32-разрядная сборка, она может ссылаться на 32-разрядные компоненты COM. Если он построен как 64-разрядная сборка, он может ссылаться на 64-разрядные компоненты COM. Тем не менее, если сборка создана как Any CPU, необходимо быть осторожным при ссылке на com-компоненты, которые не имеют эквивалента Any CPU. Возможно, лучше создать приложение в 32-разрядных и 64-разрядных формах, которые ссылаются на правильные COM-компоненты, если компоненты COM доступны в обеих формах битов.
Существует другое свойство Prefer32bit сборки (также флажок в Visual Studio), из-за которого сборка Any CPU всегда выполняется в 32-разрядном режиме на 64-разрядной системе. Это будет работать с 32-разрядными com-компонентами, но это может быть вводящим в заблуждение для всех пользователей, использующих проект позже.
Вы можете использовать атрибуты Condition в свойстве PlatformTarget для ссылки на две разные разрядности одного и того же COM-компонента. Например
<ItemGroup Condition="'$(PlatformTarget)' == 'x86'">
<COMFileReference Include="Controls\MyCom32.dll" />
</ItemGroup>
<ItemGroup Condition="'$(PlatformTarget)' == 'x64'">
<COMFileReference Include="Controls\MyCom64.dll" />
</ItemGroup>
При сборке для x86 вы ссылаетесь на 32-разрядную библиотеку COM, но при сборке для x64 вы ссылаетесь на 64-разрядную версию.
Как MSBuild разрешает ссылки на COM
Здесь описан базовый алгоритм, включая последовательность шагов при разрешении ссылки, выполняемые исполняемые файлы (например, tlbimp.exe), и вызовы API Windows.
В стандартном процессе ResolveComReference сборки пакета SDK для .NET задача вызывается в общих целевых файлах в целевом объекте с именем ResolveComReferences. Цель вызывается один раз для каждого проекта и обрабатывает все ссылки на COM, как COMReference, так и COMFileReference. Дополнительные сведения см. в статье "Задача ResolveComReference".
Задача выполняет обход дерева зависимостей, пытаясь устранить все ссылки. Большинство ошибок с отдельными ссылками не являются неустранимыми; MSBuild продолжает пытаться разрешить другие ссылки. Некоторые ошибки являются неустранимыми, если они будут влиять на все ссылки одинаково.
Если компонент COM найден в реестре или файловой системе, MSBuild обычно пытается повторно использовать ранее созданные оболочечные сборки, но при необходимости создает эти сборки. При использовании параметров по умолчанию сборки-оболочки создаются с помощью запуска tlbimp.exe и размещения в папке проекта. Он tlbimp.exe включен в пакет SDK для .NET Framework.
Задав свойства, можно настроить аргументы и параметры, предоставляемые задачей ResolveComReference . Можно настроить, следует ли использовать ранее созданные сборки-оболочки либо ранее встроенные, либо в кэше (если используется параметр кэша). Вы можете настроить выходную папку, установив значение параметра EmbedInteropTypes в True. Этот подход внедряет проецируемые типы в библиотеку или исполняемый файл, а не в отдельную сборку оболочки.
Средства диагностики
Чтобы диагностировать конкретную ошибку сборки, необходимо просмотреть подробные входные данные для задачи, которая завершилась сбоем ResolveComReference .
Подробная диагностика
Подробные диагностические данные можно задать с помощью -v:diag переключателя в командной строке MSBuild или в интегрированной среде разработки Visual Studio.
В области
В диалоговом окне
Просмотр двоичных журналов
Создайте двоичный журнал (-bl включите командную строку MSBuild) и используйте средство просмотра структурированных журналов, предоставляющее пользовательский интерфейс, который упрощает просмотр подробных шагов в сборке, значений входных параметров задачи и т. д.
Ниже приведено представление целевого ResolveComReferences объекта в структурированном средстве просмотра журналов. Можно проверить параметры и выходные данные, представляющие разрешенные пути ссылок и оболочечные сборки. В этом примере расположение сборки-оболочки развернуто для отображения расположения и имени файла созданной сборки-оболочки.
После определения имени компонента, GUID и версии, которая вызвала сбой, можно просмотреть все свойства и элементы, предоставленные задаче, ResolveComReference и собрать сведения об этом компоненте из системного реестра. Вы можете использовать редактор regedit.exeреестра, но для редактирования реестра требуются права администратора.
RegEdit
Ознакомьтесь с расположениями реестра для COM-компонентов, как для 32-разрядных, так и для 64-разрядных. Идентификаторы GUID, определяющие тип класса COM, называются идентификаторами классов (CLSID) и хранятся в среде CLSID в реестре. На 64-разрядном компьютере 64-разрядные компоненты регистрируются в разделе HKEY_LOCAL_MACHINE\Software\Classes\CLSID\, но 32-разрядные компоненты регистрируются в разделе HKEY_LOCAL_MACHINE\Software\WOW6432Node\Classes\CLSID\. На 32-разрядном компьютере 32-разрядные компоненты регистрируются в HKEY_LOCAL_MACHINE\Software\Classes\CLSID\разделе . Как правило, компонент находится путем поиска его имени или GUID в редакторе реестра. Если регистрация компонента находится в кусте реестра, как в случае с компонентами Visual Studio, может потребоваться найти и открыть куст. См. статью "Изменение реестра" для экземпляра Visual Studio.
OleView
Вы можете использовать oleview.exe для изучения отдельного типа COM и получения таких сведений, как библиотека типов и какие интерфейсы он реализует. OLEView не требует разрешений администратора и проще использовать, чем regedit.exe.
Procmon
Монитор procmon процессов можно использовать для мониторинга приложений, использующих COM во время выполнения, и отслеживать изменения реестра.
Распространенные проблемы
В этом разделе описываются распространенные проблемы, которые могут возникать при использовании COM-ссылок.
Проблемы с регистрацией
Зарегистрирован ли компонент на компьютере сборки? Если один из собственных компонентов не зарегистрирован, его можно зарегистрировать вручную с помощью средства regsvr32.exeкомандной строки. (Для этой команды требуются повышенные разрешения на компьютере.) Если компоненты являются частью пакета программного обеспечения, например Office, убедитесь, что указана правильная версия продукта, распространяющего и регистрирующего компонент. Попробуйте восстановить или переустановить программный продукт или пакет.
Подтвердите свойства COMReference. Верно ли указаны имя, GUID и версии, те же они, что и в реестре? Проверьте наличие опечаток, ошибок орфографии, несоответствий версий или других несоответствий.
Рассмотрите, является ли компонент 32-разрядным или 64-разрядным компонентом, если оба варианта доступны. Если вы нацелены на ARM64, см. статью "Создание двоичных файлов Arm64X".
При помощи COMFileReference вы ссылаетесь на COM-компонент по его файловому расположению. Проверьте путь к файлу и убедитесь, что он правильный, учитывая текущий рабочий каталог, если это относительный путь.
Проблемы с библиотекой типов
Библиотека типов требуется для создания интероперационной сборки. Библиотеки типов могут быть внедрены в двоичный файл, такой как DLL, или они могут находиться в отдельном файле, TLB-файле (.tlb расширение).
Если вы не можете найти библиотеку типов для COM-компонента, часто можно ее создать. Обычно вам не нужно создавать библиотеку типов. Он должен быть установлен с компонентом, распределенным поставщиком компонентов. Распространенные решения включают установку, обновление или переустановку пакета программного обеспечения.
Существует способ создания библиотеки типов из двоичного файла COM в редких случаях, когда это необходимо. Например, вы можете открыть двоичный файл в редакторе ресурсов Visual Studio или в стороннем редакторе ресурсов, найти ресурс библиотеки типов, экспортировать его и с помощью Сохранить файл как сохранить его как текстовый файл с расширением tlb.
Не удалось проверить зависимости
MSB3304 возникает, если возникла проблема с сканированием зависимостей ссылки. Задача ResolveComReference пытается пройти весь граф зависимостей, таким образом, любые проблемы с определением зависимостей вызывают эту ошибку. Указанное сообщение об ошибке зависит от конкретной проблемы. Если ошибка исходит из tlbimp.exe, вы также можете попробовать запустить tlbimp.exe в командной строке, чтобы получить дополнительные сведения о проблеме.
Проблемы при создании сборок оболочки
MSBuild пытается найти существующие сборки-оболочки в кэше из предыдущего запуска, если этот параметр был указан, или повторно использовать ранее созданные оболочки. При необходимости он создает оболочку. Средство tlbimp.exe используется для создания оберточных сборок. Папка создается для хранения сборок оболочки. По умолчанию папка создается в папке проекта, но её местоположение определяется параметром WrapperAssemblyLocation задачи ResolveComReference. Если этот процесс завершается ошибкой, отображается ошибка MSB3290 или MSB3283 вместе с сведениями об ошибке операционной системы. Ознакомьтесь с предлагаемыми советами по устранению неполадок для этих конкретных ошибок.
Недопустимый синтаксис COMReference или COMFileReference
Если MSBuild не удается преобразовать метаданные из файла проекта, вы получите ошибку MSB3095. В этом случае проверьте опечатки или другие ошибки в com-ссылках (или любые свойства, используемые в COM-ссылках) в файле проекта. Проверьте подэлементы элемента COMReference на соответствие ожидаемым метаданным, упомянутых в общих элементах проекта MSBuild, на наличие синтаксических ошибок или отсутствие метаданных.
Ошибки ввода-вывода файлов
Задача ResolveComReference считывает и записывает данные в файловую систему, а это значит, что она может завершиться ошибкой ввода-вывода системы, которая перехватывается MSBuild и сообщается с помощью универсального кода ошибки MSBuild. Просмотрите сведения об ошибке в сообщениях из операционной системы. Проверьте орфографию и правильность любых путей, а также для путей, созданных из свойств MSBuild, проверьте свойства, чтобы убедиться, что они определены и имеют ожидаемые значения.
Warnings
Некоторые проблемы с разрешением ссылок COM сообщаются в виде предупреждений. Возможно, вы увидите MSB3305, который появляется при вызове базовой функции, которая сообщает о несмертельной проблеме, например, при потенциальной проблеме преобразования типов. Вы можете отключить такие предупреждения, задав для свойства ResolveComReferenceSilent MSBuild значение true. Мы не рекомендуем использовать этот параметр постоянно, но это может быть полезно, если вы понимаете проблему и хотите временно отключить уведомление. Вы также можете использовать стандартные методы для подавления предупреждений. См. Подавление предупреждений сборки.
Вызовы нативных методов Windows
ResolveComReference может вызывать определенные функции API Windows. Ошибки из этих вызовов API передаются в выходные данные сборки. Здесь приведены справочные материалы.
| Имя функции | Description |
|---|---|
| FreeLibrary | Освобождает загруженный модуль динамической библиотеки (DLL). |
| GetModuleFileName | Извлекает полный путь для файла, содержащего указанный модуль. |
| LoadLibrary | Загружает указанный модуль в адресное пространство вызывающего процесса. |
| LoadRegTypeLib | Использует сведения реестра для загрузки библиотеки типов. |
| QueryPathOfRegTypeLib | Извлекает путь к зарегистрированной библиотеке типов. |