Проекты, связанные с COM-компонентами и OCX / ActiveX, чаще всего спотыкаются не на самом коде, а на границе среды выполнения, регистрации, хоста и прав доступа.
Типичные симптомы выглядят так.
- Сборка проходит, но при запуске -
0x80040154. - На своей машине разработки всё работает, а на других ПК - нет.
- При выполнении всё нормально, но падает только Designer в Visual Studio.
- При запуске от имени администратора работает, а при обычных правах ломается.
- Вы запускаете
regsvr32, а проблема почему-то не уходит.
Это не столько отдельные баги, сколько состояние, при котором где-то не совпадают базовые предположения COM.
Если сначала хочется разобраться с самой терминологией COM / ActiveX / OCX, для общей картины лучше начать со статьи Что такое COM / ActiveX / OCX - объясняем различия и связь между ними. В этой статье разбирается следующий этап - где именно на практике чаще всего застревают, включая вопросы битности Visual Studio и прав администратора.
1. Сначала вывод
Если сформулировать так, как это работает в реальной практике, получится вот что.
- Проблемы COM / OCX / ActiveX чаще возникают не из-за логики кода, а из-за несоответствий в bitness (32-бит / 64-бит), месте регистрации, хосте и правах доступа.
- Visual Studio 2022 - это 64-битный процесс, поэтому взаимодействие на этапе дизайна, рассчитанное на 32-бит, которое раньше просто работало, теперь ломается как есть.12
regsvr32- это не волшебная команда, регистрирующая что угодно. Она предназначена для нативных in-proc COM-серверов (DLL / OCX). Для публикации сборки .NET Framework в COM используетсяRegasm.exe, а для .NET 5+ / .NET 6+ / .NET 8+ регистрируют сгенерированный.comhost.dll.3456- Утверждение «работает от администратора - значит всё в порядке» опасно. Нередко компонент виден лишь случайно благодаря per-user регистрации, либо регистрация, которую положено делать инсталлятором, была вручную выполнена только на машине разработчика.378
Иначе говоря, при работе с COM / OCX / ActiveX безопаснее всего сразу смотреть на эти четыре оси.
- Какой процесс выступает хостом
- 32-бит этот процесс или 64-бит
- Где именно выполнена регистрация (HKCU / HKLM, 32-битный view / 64-битный view)
- Требуются ли для этой операции или запуска права администратора
2. Если идти от симптома к причине, картина примерно такая
| Симптом | Первое подозрение | Частая настоящая причина |
|---|---|---|
0x80040154 Class not registered |
Не зарегистрировано | На деле часто «зарегистрировано только в другой битности» или «зарегистрировано только для конкретного пользователя» |
DllRegisterServer failed: 0x80070005 |
Недостаточно прав | Попытка регистрации от обычного пользователя, либо регистрация в post-build без повышения прав |
| В VS2022 падает только Designer | Ограничение Designer | 64-битная Visual Studio не может напрямую загрузить 32-битный COM / ActiveX |
| Работает только при запуске от администратора | Проблема с правами | По сути дело чаще не в правах как таковых, а в несовпадении области регистрации или ошибках проектирования установки |
| 64-битное приложение не может вызвать 32-битный OCX | Ограничение самого механизма COM | in-proc сервер можно загрузить только в хост той же битности |
| Работает в UI-потоке, но зависает в фоновом потоке | Модель потоков | Нарушены предположения о STA / MTA, CoInitializeEx, цикле сообщений |
Официально 0x80040154 - это REGDB_E_CLASSNOTREG, дословно Class not registered.9
А 0x80070005 от regsvr32 официально описывается как случай, когда не хватает прав администратора для записи в реестр или System32.10
Здесь важно не слишком доверять названию ошибки.
Например, Class not registered вовсе не обязательно означает «полностью не зарегистрировано» - это происходит и тогда, когда компонент зарегистрирован в другом view реестра, либо зарегистрирован в месте, видимом только конкретному пользователю.117
3. Ловушки, связанные с битностью Visual Studio
3.1. Visual Studio 2022 стала 64-битной
Это самое частое место, где спотыкаются в сегодняшней разработке COM / ActiveX.
В Visual Studio 2022 devenv.exe - исключительно 64-бит.1
Из-за этого в дизайнерском опыте WinForms сама Visual Studio не может напрямую загружать 32-битные компоненты. Microsoft прямо указывает, что, поскольку Visual Studio 2022 - это 64-битный процесс, она не может загружать 32-битные .NET / COM / ActiveX компоненты.2
Иными словами, то, что раньше держалось на предположениях вроде:
- проект собран под x86;
- используемый ActiveX тоже x86;
- сама Visual Studio - 32-бит,
в VS2022 превращается в перекос:
- приложение при выполнении по-прежнему работает как x86;
- но Designer выполняется на стороне 64-битной Visual Studio.
В результате получается довольно неприятная ситуация: приложение при выполнении живо, а падает только Designer.2
3.2. Переход на AnyCPU не всегда решает проблему
Это ещё одно частое заблуждение.
AnyCPU - не волшебство, которое делает нейтральными и зависимости.
Как поясняет Microsoft, даже компонент, выглядящий как AnyCPU, всё равно создаёт проблему на этапе дизайна в Visual Studio 2022, если дальше по цепочке он ссылается на COM / ActiveX, жёстко привязанный к 32-бит.2
Поэтому, если переход на AnyCPU не убирает ошибку, быстрее заподозрить следующее:
- нет ли дальше по цепочке этой сборки 32-битной нативной зависимости;
- не привязан ли ActiveX / OCX жёстко к x86;
- нет ли кода, загружаемого только на этапе дизайна.
3.3. Ловушка System32 и SysWOW64
На Windows x64 названия папок и их реальное назначение расходятся, что часто сбивает с толку.
Microsoft Learn поясняет, что на x64 Windows %windir%\System32 предназначен для 64-битных приложений. 32-битная сторона перенаправляется в другое место файловым редиректором WOW64.12
С реестром та же история: редиректор реестра WOW64 показывает 32-битному и 64-битному коду разные логические view.11
Поэтому при локальном разборе проблемы безопаснее явно указывать, какую именно битность regsvr32 вы используете.
# Чтобы зарегистрировать 64-битный DLL / OCX
C:\Windows\System32\regsvr32.exe vendor.ocx
# Чтобы зарегистрировать 32-битный DLL / OCX на x64 Windows
C:\Windows\SysWOW64\regsvr32.exe vendor.ocx
Неприятная сторона этой ловушки в том, что при регистрации не в той версии компонент остаётся невидимым для целевого процесса, хотя формально «зарегистрирован». В итоге получается такая картина:
regsvr32отработал успешно;- но приложение всё равно выдаёт
0x80040154; - в реестре запись как будто есть;
- но на самом деле вы смотрите в другой view.
3.4. regsvr32 не регистрирует абсолютно всё
Ещё одна область, полная заблуждений.
Нативные in-proc COM-серверы обычно поддерживают саморегистрацию, экспортируя DllRegisterServer / DllUnregisterServer.3
regsvr32 - это инструмент именно для таких DLL / OCX.4
С другой стороны, если нужно использовать сборку .NET Framework из COM, стандартный инструмент - Regasm.exe. Microsoft Learn также поясняет, что для регистрации сборок, используемых в COM, применяется Regasm.exe.514
Кроме того, публикация в COM для .NET 5+ / .NET 6+ / .NET 8+ устроена немного иначе: при сборке с <EnableComHosting>true</EnableComHosting> создаётся файл *.comhost.dll, и именно его регистрируют через regsvr32.6
Если обобщить, получается вот такая картина.
| Что нужно опубликовать | Типичный способ регистрации |
|---|---|
| Нативный C++ DLL / OCX | regsvr32 |
| Сборка .NET Framework, опубликованная в COM | Regasm.exe |
| Публикация в COM для .NET 5+ / 6+ / 8+ | Сгенерированный .comhost.dll через regsvr32 |
Если перепутать эти способы, часто возникает такой сценарий:
regsvr32применяют к управляемой DLL;- естественно,
DllRegisterServerне находится; - отсюда делают неверный вывод: «DLL повреждена».
В мире, где нужны библиотеки типов (VBA / VB6 / некоторые сценарии раннего связывания), отдельной проблемой становится ещё и генерация и регистрация TLB. В .NET Framework библиотеку типов можно сгенерировать и зарегистрировать через Regasm.exe /tlb, и Microsoft также поясняет, что «регистрация типов» и «регистрация библиотеки типов» - разные действия.15
4. Ловушки, связанные с правами администратора
4.1. Регистрация в post-build, которая срабатывает только от администратора
В сборках C++ в Visual Studio вызов regsvr32.exe из build event или custom build step - вполне обычная практика. Microsoft Learn даже приводит пример post-build события с регистрацией через regsvr32.exe.16
Однако возможность так сделать и безопасность так делать - разные вещи.
При запуске regsvr32 от имени обычного пользователя запись в реестр или System32 может быть недоступна, из-за чего возникает 0x80070005. В KB Microsoft причина также обозначена как отсутствие прав администратора.10
Здесь часто случается такой сценарий:
- Visual Studio запущена с обычными правами, сборка проходит;
- но регистрация в post-build проваливается;
- ошибку в логе пропускают;
- на месте случайно работает прежняя, уже устаревшая регистрация;
- в чистом окружении, разумеется, ничего не работает.
Для таких проектов базовый подход - разделять сборку и регистрацию.
- Сборка только создаёт бинарные файлы
- Регистрация выполняется отдельным явным шагом установки / скриптом / инсталлятором
- В CI шаги, требующие регистрации, выносятся в отдельную задачу от сборки
Само это разделение заметно снижает число подобных инцидентов.
4.2. Смешение per-user и per-machine регистрации ломает работу
Если держать в голове только «COM смотрит в HKCR», здесь неизбежно застрянете.
На самом деле, как поясняет Microsoft Learn, COM сначала смотрит в HKEY_CURRENT_USER\Software\Classes, а затем обрабатывает общесистемную информацию.3
А HKEY_CLASSES_ROOT - это объединённое представление HKLM\Software\Classes и HKCU\Software\Classes.717
Иначе говоря, вполне обычна такая ситуация:
- разработчик A вручную зарегистрировал компонент под своей учётной записью;
- под учётной записью A всё работает;
- у разработчика B не работает;
- под сервисной учётной записью тоже не работает;
- при запуске от администратора поведение меняется.
Более того, Microsoft указывает, что приложениям, требующим прав администратора, следует регистрировать зависимые COM-объекты в per-machine хранилище конфигурации COM при установке.87
Поэтому в команде разработки стоит чётко разграничивать:
- это регистрация только для разработки, используемая лишь вашей собственной учётной записью;
- это продакшн-регистрация, используемая всеми пользователями машины;
- это регистрация, к которой обращаются сервисы или приложения с повышенными правами.
Если оставить это размытым, получаются истории вроде «почему-то работает только от администратора» или «работает в расширении Explorer, но не в сервисе».
4.3. Постоянный запуск Visual Studio «от имени администратора» - не решение
Бывают ситуации, когда это действительно нужно. Но если держать Visual Studio постоянно запущенной с повышенными правами, можно спрятать за повышением прав IDE проблему, которую на самом деле должен решать инсталлятор или скрипт регистрации.
Более того, сама Visual Studio при запуске с повышенными правами по-другому обращается с per-user расширениями. Microsoft Learn описывает настройку, при которой запуск Visual Studio elevated отключает per-user расширения.18
Поэтому на практике удобнее так:
- повседневная разработка ведётся с обычными правами;
- шаги, требующие регистрации, выполняются только в явно повышенном Developer Command Prompt / PowerShell / инсталляторе;
- если что-то «воспроизводится только от администратора», само это предположение стоит зафиксировать как часть спецификации.
Так дальше будет меньше проблем.
5. Специфичные ловушки ActiveX / OCX
5.1. Лицензия на этапе дизайна и лицензия времени выполнения - разные вещи
Незаметно неприятный момент в OCX / ActiveX - это лицензирование.
Особенно у старых элементов управления ActiveX лицензия для этапа дизайна и лицензия времени выполнения могут быть разделены. В документации MFC ActiveX тоже описан механизм разделения design-time и run-time через файлы и ключи лицензий.1920
В этом мире случается вот что:
- во время выполнения компонент используется без проблем;
- но при попытке разместить его на форме появляется ошибка «нет лицензии»;
- на машине разработчика A разместить можно;
- на машине разработчика B - нельзя.
Ошибки вроде «лицензия для этого компонента не найдена» или «нет подходящей лицензии» - для старого ActiveX не редкость.21
5.2. В момент размещения на WinForms уже подключается обёртка
Когда ActiveX используется в WinForms, Windows Forms не хостит ActiveX напрямую.
Как поясняет документация Microsoft Learn для Aximp.exe, ActiveX Control Importer генерирует обёртку для WinForms на основе библиотеки типов COM и работает с ней как с элементом управления на базе AxHost.2223
Иначе говоря, проблема существует не на одном слое, а сразу на нескольких:
- исходный OCX / ActiveX;
- библиотека типов;
- сгенерированный interop / wrapper;
- Designer / runtime WinForms.
Из-за этого случается следующее:
- замена OCX вендора изменила сигнатуры событий;
- повторное добавление ссылки перегенерировало обёртку и вызвало огромный diff;
- результат генерации interop чуть отличается от машины к машине разработчика.
Появление компонента в Choose Toolbox Items ещё не гарантия.
Возможность разместить компонент в Designer, приход событий во время выполнения и целостность обёртки на целевой машине развёртывания безопаснее проверять по отдельности.
5.3. Недооценка STA / MTA и цикла сообщений приводит к зависаниям
COM необходимо инициализировать через CoInitializeEx на каждом потоке, который его использует. Microsoft Learn прямо указывает, что каждый поток, использующий COM, должен отдельно вызвать CoInitializeEx.24
Кроме того, для STA (single-threaded apartment) требуется цикл сообщений.2425
Особенно UI-ориентированные OCX / ActiveX чаще всего рассчитаны на STA, поэтому возникает неприятная картина:
- в UI-потоке всё работает;
- при переносе в
Task.Runили пул потоков всё зависает; - события не приходят обратно;
- воспроизводится лишь иногда.
Кроме того, в STA действует правило: нельзя просто копировать интерфейсные указатели в другой поток, при необходимости их нужно маршалировать.2425
Подобные дефекты гораздо менее дружелюбны, чем 0x80040154: видны только зависания, отсутствие ответа, редкие падения, поэтому на них уходит не меньше времени, чем на проблемы с реестром.
6. Порядок разбора, который эффективен на практике
На практике быстрее не углубляться сразу, а резать проблему в таком порядке.
6.1. Сначала зафиксировать «какой процесс какой битности»
Это первое, на что нужно смотреть.
- Что выступает хостом (Designer Visual Studio / собственное приложение / Office / Access / Explorer / среда совместимости браузера)
- 32-бит этот хост или 64-бит
- 32-бит или 64-бит целевой DLL / OCX
- Это in-proc или out-of-proc
Если начать разбираться в реестре, оставив это неопределённым, почти наверняка заблудитесь.
6.2. Затем проверить «вид регистрации»
Следующее, что нужно проверить - чем правильно регистрировать что.
- Нативный DLL / OCX →
regsvr32 - Публикация .NET Framework в COM →
Regasm.exe - Публикация .NET 5+ / 6+ / 8+ в COM →
.comhost.dll - DLL без саморегистрации вообще → это не задача для
regsvr32
Одна только эта классификация останавливает значительную часть ошибочных действий.
6.3. После этого посмотреть, «куда попала регистрация»
Смотреть только в HKCR недостаточно. Нужно проверить:
HKCU\Software\ClassesHKLM\Software\Classes- при необходимости 32-битный / 64-битный view реестра
- целевой ProgID / CLSID / TypeLib
InprocServer32/LocalServer32- ThreadingModel
- фактический путь к целевой DLL
Одного факта «есть в HKCR» недостаточно - это имеет смысл только тогда, когда известно ещё и кто смотрит, с какой битностью и через какой view.711
6.4. Наконец, проверить, не маскируются ли проблемы правами доступа
В последнюю очередь нужно проверить, действительно ли проблема в правах, или же права просто делают видимой другую регистрацию.
- Меняется ли поведение между обычным пользователем и администратором
- Что меняется при повышении прав Visual Studio
- Воспроизводится ли проблема под сервисной учётной записью или другим пользователем
- Сохраняется ли работоспособность в чистом окружении, развёрнутом через инсталлятор
Если смотреть только на одну машину разработки, здесь легко ошибиться в выводах.
7. Решения, принятые заранее, снижают число инцидентов
В разработке и сопровождении COM / ActiveX / OCX часто важнее не техника реализации, а то, как заранее выстроена эксплуатация.
7.1. Заранее определить политику битности
В первую очередь решается вот что.
- Идти на x86 фиксированно
- Считать x64 основной платформой
- Поддерживать обе
- Обязан ли данный компонент быть in-proc
Особенно если OCX вендора жёстко привязан к x86, игнорирование этого при переводе только самого приложения на x64 позже приведёт к затыку. Эта тема связана с более крупным вопросом архитектуры - см. также Как вызвать 64-битную DLL из 32-битного приложения - кейс, где помогает COM-мост.
7.2. Определить стратегию регистрации
Регистрацию тоже не стоит делать по случайному принципу.
- Используется на всей машине → per-machine регистрация через инсталлятор
- Используется только этим пользователем → осознанно использовать per-user
- Ограничивается только собственным приложением → рассмотреть registration-free COM
- Нужно только для разработки → замкнуть в явном dev-скрипте настройки
Registration-free COM хранит информацию активации не в реестре, а в манифесте, что делает его эффективным средством снижения ада регистрации. Официально описаны как registration-free COM на стороне Win32, так и RegFree COM на стороне .NET.26627
7.3. Не оставлять слишком много артефактов вне системы контроля версий
Классическая беда проектов OCX / ActiveX - разбросанность зависимостей.
- сам OCX;
- зависимые DLL;
- TLB;
.lic;- interop DLL;
- обёртка AxHost;
- скрипты регистрации;
- тестовый хост.
Если всё это существует только на локальной машине конкретного человека, через несколько месяцев инцидент гарантирован.
Как минимум рядом с кодом стоит хранить:
- какая версия предполагается;
- что и в каком порядке устанавливается;
- какой командой выполняется регистрация;
- для x86 или x64 это предназначено.
8. С какими консультациями эта тема хорошо сочетается
По этой теме ценность часто даёт уже сам разбор причин и прояснение политики, ещё до начала полномасштабной переработки.
Например, эта тема особенно хорошо сочетается со следующими запросами:
- разложить причины
0x80040154или0x80070005по bitness / регистрации / правам доступа; - после перехода на Visual Studio 2022 сломался Designer, и хочется понять, что можно спасти;
- сохранить OCX вендора, перенеся окружение вокруг него на .NET и C#;
- решить, насколько продлевать жизнь x86-зафиксированным активам и где начинать bridge / wrap / replace;
- отказаться от ручной зависимости от
regsvr32и пересмотреть install / deploy.
По вопросу выбора между сохранить / обернуть / заменить также полезна статья Как сегодня обращаться с ActiveX / OCX - таблица решений «сохранить, обернуть, заменить».
9. Итог
Когда разработка или сопровождение COM-компонентов или OCX / ActiveX упирается в проблему, причина почти всегда сводится к одной из этих четырёх.
- Не совпадает bitness
- Неверно выбран способ регистрации
- Область регистрации (HKCU / HKLM, 32-битный / 64-битный view) не совпадает
- Состояние, видимое лишь случайно благодаря правам доступа, ошибочно принимается за нормальное
Из-за перехода Visual Studio 2022 на 64-бит старые решения, которые раньше «как-то работали», стали проявлять свои проблемы гораздо заметнее.12 Именно поэтому при работе с COM / OCX / ActiveX кратчайший путь - сначала выровнять предположения об окружении, а уже потом писать код.
Вместо того чтобы считать, сколько раз запущен regsvr32, полезнее разобраться:
- какой процесс выступает хостом;
- какой битности этот процесс;
- куда должна попасть регистрация;
- действительно ли эта регистрация требует прав администратора;
- рассматриваются ли Designer и runtime по отдельности.
Такой подход решает проблему намного быстрее.
Справочные материалы
-
Microsoft Learn, Visual Studio 2022 version 17.0 Release Notes -
devenv.exe is now 64-bit only. ↩ ↩2 ↩3 -
Microsoft Learn, Troubleshoot 32-bit problems - Windows Forms - о том, что Visual Studio 2022 является 64-битным процессом и не может напрямую загружать 32-битные .NET / COM / ActiveX компоненты, а также об ограничениях out-of-process designer. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Classes and Servers - регистрация COM, HKCU / HKCR, саморегистрация и
DllRegisterServer. ↩ ↩2 ↩3 ↩4 -
Microsoft Learn, regsvr32 - синтаксис и назначение
regsvr32. ↩ ↩2 -
Microsoft Learn, Registering Assemblies with COM - регистрация .NET Framework для COM выполняется через
Regasm.exe. ↩ ↩2 -
Microsoft Learn, Exposing .NET Core components to COM -
EnableComHosting, генерируемый.comhost.dll,regsvr32,EnableRegFreeCom. ↩ ↩2 ↩3 -
Microsoft Learn, Merged View of HKEY_CLASSES_ROOT - HKCR как объединённое представление HKLM и HKCU. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, HKEY_CLASSES_ROOT Key - рекомендация регистрировать зависимые COM-объекты в per-machine конфигурации для приложений, требующих прав администратора. ↩ ↩2
-
Microsoft Learn, COM Error Codes (Generic) (Winerror.h) -
REGDB_E_CLASSNOTREG (0x80040154)и другие. ↩ -
Microsoft Learn, You receive 0x80070005 error when you try to register a DLL by using Regsvr32.exe - типичный случай ошибки регистрации DLL из-за недостатка прав. ↩ ↩2
-
Microsoft Learn, Registry Redirector - 32-битный / 64-битный view реестра под WOW64. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, File System Redirector -
%windir%\System32на x64 Windows и перенаправление файловой системы через WOW64. ↩ -
Microsoft Learn, Overview of compatibility considerations for 32-bit programs on 64-bit versions of Windows - перенаправление файлов / реестра под WOW64. ↩
-
Microsoft Learn, Regasm.exe (Assembly Registration Tool) - назначение
Regasm.exeи опции вроде/tlb. ↩ -
Microsoft Learn, Packaging a .NET Framework Assembly for COM - библиотеки типов и
Regasm.exe /tlb. ↩ -
Microsoft Learn, Understanding Custom Build Steps and Build Events - пример использования
regsvr32.exeв post-build событии. ↩ -
Microsoft Learn, Windows registry for advanced users -
HKCU\Software\ClassesиHKLM\Software\Classes, поведение HKCR. ↩ -
Microsoft Learn, Find, install, and manage extensions for Visual Studio - обращение с per-user расширениями при запуске с повышенными правами. ↩
-
Microsoft Learn, MFC ActiveX Controls: Licensing an ActiveX Control - лицензии design-time / run-time,
.LIC. ↩ -
Microsoft Learn, Application Settings, MFC ActiveX Control Wizard - генерация run-time лицензии и файл
.lic. ↩ -
Microsoft Learn, License information for this component not found. You don’t have an appropriate license to use this functionality in the design environment. ↩
-
Microsoft Learn, Aximp.exe (Windows Forms ActiveX Control Importer) - преобразование ActiveX в обёртку для WinForms. ↩
-
Microsoft Learn, AxHost Class - обёртка на основе AxHost, генерируемая ActiveX Control Importer. ↩
-
Microsoft Learn, Initializing the COM Library -
CoInitializeEx, инициализация на каждом потоке, цикл сообщений STA. ↩ ↩2 ↩3 -
Microsoft Learn, Single-Threaded Apartments - цикл сообщений STA, маршалинг,
ThreadingModel. ↩ ↩2 -
Microsoft Learn, Creating Registration-Free COM Objects - registration-free COM через activation context. ↩
-
Microsoft Learn, Registration-Free COM Interop - registration-free COM interop в .NET Framework. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Office 2024/Microsoft 365: почему не работает ActiveX и как это диагностировать
Разбираем порядок диагностики, когда ActiveX не работает в Office 2024/Microsoft 365: отключение по умолчанию, несовпадение 32-бит/64-бит...
Что такое COM / ActiveX / OCX - объясняем различия и связь между ними
Разбираем с практической точки зрения, что такое COM, что такое ActiveX и что такое OCX: их различия и связь, связь с OLE, где они примен...
Как сегодня поступать с ActiveX / OCX - таблица решений: оставить, обернуть или заменить
Разбираем, что выбрать при обнаружении ActiveX / OCX — оставить, обернуть или заменить, — учитывая 32-бит/64-бит, регистрацию, зависимост...
Пример моста COM для вызова 64-битной DLL из 32-битного приложения
Когда 32-битное приложение не может напрямую вызвать 64-битную DLL, их можно связать через мост COM. Рассматриваем этот подход, включая о...
Аутсорсинг и контрактная разработка Windows-приложения: что стоит прояснить перед заказом
Перед тем как заказать аутсорсинг или контрактную разработку Windows-приложения, разберём, что нужно прояснить: доработка существующего П...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Миграция ActiveX
Решения о сохранении, обёртке или замене компонентов COM / ActiveX / OCX.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Использование и перенос существующих активов
Помогаем использовать и переносить активы COM / ActiveX / OCX и зависимости 32/64 бит.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Как разбираться с ошибкой 0x80040154 (Class not registered)?
- Официально это REGDB_E_CLASSNOTREG - дословно «класс не зарегистрирован», но это не всегда означает полное отсутствие регистрации. Такое случается и тогда, когда компонент зарегистрирован только в другой битности реестра, либо только в HKCU, видимом лишь одному пользователю. Кратчайший путь - сначала зафиксировать, 32-бит или 64-бит хост-процесс, затем проверить, правильным ли способом выполнена регистрация, и наконец по порядку посмотреть, куда именно она попала: в HKCU или HKLM, в 32-битный или 64-битный view.
- Почему компонент не работает даже после успешной регистрации через regsvr32?
- regsvr32 предназначен для нативных in-proc COM-серверов (DLL / OCX), экспортирующих DllRegisterServer, и не является волшебной командой, регистрирующей всё подряд. Для публикации сборки .NET Framework в COM используется Regasm.exe, а начиная с .NET 5 регистрируют через regsvr32 сгенерированный файл .comhost.dll, который создаётся при включённом EnableComHosting. Кроме того, на x64 Windows нужно различать regsvr32 из System32 для 64-бит и из SysWOW64 для 32-бит: если зарегистрировать не в той версии, регистрация формально пройдёт успешно, но останется невидимой для целевого процесса.
- Почему в Visual Studio 2022 ломается только Designer?
- Потому что devenv.exe в Visual Studio 2022 - это 64-битный процесс, который не может напрямую загружать 32-битные COM- / ActiveX-компоненты. Приложение при выполнении может нормально работать в режиме x86, но Designer выполняется в 64-битном процессе самой Visual Studio, отсюда и странный перекос: во время выполнения всё живо, а падает только Designer. Переход на AnyCPU тоже не решает проблему сам по себе, если где-то дальше по цепочке зависимостей остаётся жёстко привязанный к 32-бит COM- / ActiveX-компонент.
- Почему компонент работает при запуске от имени администратора, но не работает при обычных правах?
- Чаще всего суть проблемы не в самих правах, а в несоответствии области регистрации или ошибках в проектировании установки. COM сначала смотрит в HKCU\Software\Classes, а сам HKEY_CLASSES_ROOT - это объединённое представление HKLM и HKCU. Если разработчик A зарегистрировал компонент вручную под своей учётной записью, вполне обычная ситуация - что у A всё работает, а у других пользователей или под сервисной учётной записью нет. Базовый подход - разделять регистрацию для разработки (per-user) и продакшн-регистрацию через инсталлятор (per-machine), а также отделять сборку от регистрации.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.
Публичные ссылки