Ловушки регистрации и bitness при разработке COM/OCX/ActiveX

· · COM, ActiveX, OCX, Visual Studio, Разработка Windows, 32-бит, 64-бит, Interop

Проекты, связанные с COM-компонентами и OCX / ActiveX, чаще всего спотыкаются не на самом коде, а на границе среды выполнения, регистрации, хоста и прав доступа.

Типичные симптомы выглядят так.

  • Сборка проходит, но при запуске - 0x80040154.
  • На своей машине разработки всё работает, а на других ПК - нет.
  • При выполнении всё нормально, но падает только Designer в Visual Studio.
  • При запуске от имени администратора работает, а при обычных правах ломается.
  • Вы запускаете regsvr32, а проблема почему-то не уходит.

Это не столько отдельные баги, сколько состояние, при котором где-то не совпадают базовые предположения COM.

Если сначала хочется разобраться с самой терминологией COM / ActiveX / OCX, для общей картины лучше начать со статьи Что такое COM / ActiveX / OCX - объясняем различия и связь между ними. В этой статье разбирается следующий этап - где именно на практике чаще всего застревают, включая вопросы битности Visual Studio и прав администратора.

1. Сначала вывод

Если сформулировать так, как это работает в реальной практике, получится вот что.

  1. Проблемы COM / OCX / ActiveX чаще возникают не из-за логики кода, а из-за несоответствий в bitness (32-бит / 64-бит), месте регистрации, хосте и правах доступа.
  2. Visual Studio 2022 - это 64-битный процесс, поэтому взаимодействие на этапе дизайна, рассчитанное на 32-бит, которое раньше просто работало, теперь ломается как есть.12
  3. regsvr32 - это не волшебная команда, регистрирующая что угодно. Она предназначена для нативных in-proc COM-серверов (DLL / OCX). Для публикации сборки .NET Framework в COM используется Regasm.exe, а для .NET 5+ / .NET 6+ / .NET 8+ регистрируют сгенерированный .comhost.dll.3456
  4. Утверждение «работает от администратора - значит всё в порядке» опасно. Нередко компонент виден лишь случайно благодаря 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.

1113

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

Иначе говоря, проблема существует не на одном слое, а сразу на нескольких:

  1. исходный OCX / ActiveX;
  2. библиотека типов;
  3. сгенерированный interop / wrapper;
  4. 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\Classes
  • HKLM\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 упирается в проблему, причина почти всегда сводится к одной из этих четырёх.

  1. Не совпадает bitness
  2. Неверно выбран способ регистрации
  3. Область регистрации (HKCU / HKLM, 32-битный / 64-битный view) не совпадает
  4. Состояние, видимое лишь случайно благодаря правам доступа, ошибочно принимается за нормальное

Из-за перехода Visual Studio 2022 на 64-бит старые решения, которые раньше «как-то работали», стали проявлять свои проблемы гораздо заметнее.12 Именно поэтому при работе с COM / OCX / ActiveX кратчайший путь - сначала выровнять предположения об окружении, а уже потом писать код.

Вместо того чтобы считать, сколько раз запущен regsvr32, полезнее разобраться:

  • какой процесс выступает хостом;
  • какой битности этот процесс;
  • куда должна попасть регистрация;
  • действительно ли эта регистрация требует прав администратора;
  • рассматриваются ли Designer и runtime по отдельности.

Такой подход решает проблему намного быстрее.


Справочные материалы

  1. Microsoft Learn, Visual Studio 2022 version 17.0 Release Notes - devenv.exe is now 64-bit only 2 3

  2. Microsoft Learn, Troubleshoot 32-bit problems - Windows Forms - о том, что Visual Studio 2022 является 64-битным процессом и не может напрямую загружать 32-битные .NET / COM / ActiveX компоненты, а также об ограничениях out-of-process designer.  2 3 4 5

  3. Microsoft Learn, Classes and Servers - регистрация COM, HKCU / HKCR, саморегистрация и DllRegisterServer 2 3 4

  4. Microsoft Learn, regsvr32 - синтаксис и назначение regsvr32 2

  5. Microsoft Learn, Registering Assemblies with COM - регистрация .NET Framework для COM выполняется через Regasm.exe 2

  6. Microsoft Learn, Exposing .NET Core components to COM - EnableComHosting, генерируемый .comhost.dll, regsvr32, EnableRegFreeCom 2 3

  7. Microsoft Learn, Merged View of HKEY_CLASSES_ROOT - HKCR как объединённое представление HKLM и HKCU.  2 3 4 5

  8. Microsoft Learn, HKEY_CLASSES_ROOT Key - рекомендация регистрировать зависимые COM-объекты в per-machine конфигурации для приложений, требующих прав администратора.  2

  9. Microsoft Learn, COM Error Codes (Generic) (Winerror.h) - REGDB_E_CLASSNOTREG (0x80040154) и другие. 

  10. Microsoft Learn, You receive 0x80070005 error when you try to register a DLL by using Regsvr32.exe - типичный случай ошибки регистрации DLL из-за недостатка прав.  2

  11. Microsoft Learn, Registry Redirector - 32-битный / 64-битный view реестра под WOW64.  2 3 4

  12. Microsoft Learn, File System Redirector - %windir%\System32 на x64 Windows и перенаправление файловой системы через WOW64. 

  13. Microsoft Learn, Overview of compatibility considerations for 32-bit programs on 64-bit versions of Windows - перенаправление файлов / реестра под WOW64. 

  14. Microsoft Learn, Regasm.exe (Assembly Registration Tool) - назначение Regasm.exe и опции вроде /tlb

  15. Microsoft Learn, Packaging a .NET Framework Assembly for COM - библиотеки типов и Regasm.exe /tlb

  16. Microsoft Learn, Understanding Custom Build Steps and Build Events - пример использования regsvr32.exe в post-build событии. 

  17. Microsoft Learn, Windows registry for advanced users - HKCU\Software\Classes и HKLM\Software\Classes, поведение HKCR. 

  18. Microsoft Learn, Find, install, and manage extensions for Visual Studio - обращение с per-user расширениями при запуске с повышенными правами. 

  19. Microsoft Learn, MFC ActiveX Controls: Licensing an ActiveX Control - лицензии design-time / run-time, .LIC

  20. Microsoft Learn, Application Settings, MFC ActiveX Control Wizard - генерация run-time лицензии и файл .lic

  21. Microsoft Learn, License information for this component not found. You don’t have an appropriate license to use this functionality in the design environment. 

  22. Microsoft Learn, Aximp.exe (Windows Forms ActiveX Control Importer) - преобразование ActiveX в обёртку для WinForms. 

  23. Microsoft Learn, AxHost Class - обёртка на основе AxHost, генерируемая ActiveX Control Importer. 

  24. Microsoft Learn, Initializing the COM Library - CoInitializeEx, инициализация на каждом потоке, цикл сообщений STA.  2 3

  25. Microsoft Learn, Single-Threaded Apartments - цикл сообщений STA, маршалинг, ThreadingModel 2

  26. Microsoft Learn, Creating Registration-Free COM Objects - registration-free COM через activation context. 

  27. Microsoft Learn, Registration-Free COM Interop - registration-free COM interop в .NET Framework. 

Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.

Эти страницы показывают тему статьи в более широком контексте услуг и решений.

Статья напрямую связана со следующими услугами.

Частые вопросы

Вопросы, которые часто возникают при консультациях по теме статьи.

Как разбираться с ошибкой 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, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

Публичные ссылки

Вернуться в блог