Как сегодня поступать с ActiveX / OCX: оставить, обернуть или заменить

· Обновлено: · · COM, ActiveX, OCX, .NET, разработка под Windows, модернизация

История изменений (2 обновлений, последнее 30 Aug 2026)

Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.

Русский текст переписан как полноценный технический перевод, а не калька с японского. Утверждения статьи не менялись.
В 5.2 добавлен DllSurrogate — вариант, который стоит рассмотреть до того, как писать собственный вспомогательный EXE. Если компонент является in-proc COM-сервером, достаточно добавить AppID к его CLSID и пустой DllSurrogate под этим AppID, чтобы вынести его из процесса, не написав ни строки своего кода. При этом суррогат не устраняет разницу в разрядности: исчезает только требование находиться в одном процессе, а вызовы становятся межпроцессными, со всеми издержками маршалинга и межпроцессного взаимодействия. Новая таблица разграничивает случаи, которые покрывает суррогат, и случаи, где всё же нужен собственный вспомогательный EXE; добавлены также два источника. Сама процедура регистрации описана в другой статье, сюда вынесена только ссылка на неё. Открыть версию до этого обновления (DOI: 10.5281/zenodo.21619663)
Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.21619662)

Приведённые ниже DOI относятся к ранее зарегистрированным архивным версиям, которые могут отличаться от текущего текста. Для ссылки на текущий текст используйте URL этой страницы.

Го Комура (2026). Как сегодня поступать с ActiveX / OCX: оставить, обернуть или заменить. KomuraSoft LLC. https://comcomponent.com/ru/blog/2026/03/12/001-activex-ocx-keep-wrap-replace-decision-table/

DOI (зарегистрированный архив)
10.5281/zenodo.21619662
DOI (последняя зарегистрированная версия)
10.5281/zenodo.22170275

Проекты, где звучат слова ActiveX / OCX, обычно сразу даются тяжело.

  • VB6 или старые приложения на C++ / MFC всё ещё в работе
  • SDK промышленного оборудования или измерительных приборов поставляется только как OCX
  • внутренний веб-портал завязан на ActiveX и не может выйти из режима IE
  • хочется уйти с 32 бит на 64, но один OCX этому мешает

И «выбросить всё, потому что это старое», и «сохранить навечно, потому что оно работает» — одинаково грубые решения. Главное — понять, является ли этот ActiveX / OCX простым UI-компонентом или границей, в которую уже встроена бизнес-логика и спецификация оборудования.

В статье разбираем, в каком порядке проще решить — оставить, обернуть или заменить — когда вы находите ActiveX / OCX.

В качестве примеров рассматриваются такие случаи:

  • существующие настольные приложения на VB6 / MFC / WinForms;
  • поэтапный переход на C# / .NET;
  • устаревшие экраны с WebBrowser / режимом IE;
  • Windows-приложения с элементами ActiveX от сторонних вендоров.

Содержание

  1. Сначала вывод (в двух словах)
  2. Что в этой статье понимается под ActiveX / OCX
  3. Таблица решений, с которой стоит начать
    • 3.1. Общая картина
    • 3.2. Решение оставить
    • 3.3. Решение обернуть
    • 3.4. Решение заменить
    • 3.5. Зависимость от браузера рассматриваем отдельно
  4. Моменты, которые легко сбивают с толку
    • 4.1. UI-компонент или компонент со встроенной спецификацией
    • 4.2. 32-бит / 64-бит и границы процессов
    • 4.3. Регистрация, распространение, права, лицензии
    • 4.4. STA / цикл сообщений / обратные вызовы
    • 4.5. Есть ли тесты, можно ли наблюдать за поведением
  5. Рекомендации по типовым сценариям
    • 5.1. Внутреннее настольное приложение, которое до сих пор стабильно работает
    • 5.2. Хотите перенести 32-битный OCX на 64-битную сторону
    • 5.3. Экраны, завязанные на IE / WebBrowser
    • 5.4. ActiveX с управлением оборудованием или собственной спецификацией
  6. Частые антипаттерны
  7. Чек-лист для начала миграции
  8. Краткая шпаргалка по выбору
  9. Итог
  10. С какими вопросами к нам обращаться
  11. Источники

На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 24, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle

1. Сначала вывод (в двух словах)

  • Увидев ActiveX / OCX, в первую очередь нужно судить не «старое ли это», а что именно взял на себя этот компонент
  • Если это простой UI-компонент, заменить его сравнительно легко
  • Если он несёт управление оборудованием, отчёты, собственный формат файлов или многолетние особенности эксплуатации, безопаснее сначала обернуть его, а не сразу переписывать заново
  • Если он стабильно работает на настольном хосте и область изменений невелика, решение оставить как есть вполне обосновано
  • У зависимости от ActiveX в браузере продлить жизнь можно, но на долгую перспективу рассчитывать не стоит, так что здесь стоит смотреть на замену как на приоритет
  • 32-битный OCX нельзя напрямую загрузить в 64-битный процесс. Усилием воли эту границу не обойти
  • Регистрация, зависимые DLL, права администратора, лицензии, STA / MTA — трение вне самой реализации часто оказывается самым сложным местом
  • И «на всякий случай переписать всё», и «заморозить навсегда из страха» — варианты с высокой вероятностью сбоев

Иначе говоря, порядок принятия решения такой.

  1. Что несёт в себе этот OCX
  2. Обязательно ли использовать его в том же процессе
  3. Не застрянете ли вы на 32-бит / 64-бит, регистрации или зависимости от браузера
  4. Стоит ли сначала создать тестируемую границу, а потом уже заменять

При таком порядке разобраться получается заметно проще.

Порядок принятия решенияСмотрите по порядку: что несёт этот OCX, нужен ли тот же процесс, не застрянете ли на разрядности, регистрации или браузере, и стоит ли сначала сделать тестируемую границу, а потом заменять.Что несёт этот OCXНужен ли тот же процессЗастрянете ли на bitness, регистрации, браузереСначала граница, потом замена?

Рис. 1: Смотрите не на «старое ли это», а в этом порядке — тогда «оставить / обернуть / заменить» складывается проще.

2. Что в этой статье понимается под ActiveX / OCX

Сначала зафиксируем, как в этой статье используются термины.

Термин Значение в этой статье
COM Бинарно-совместимая компонентная модель Windows. Основа публичных интерфейсов, регистрации, Apartment Model и так далее
ActiveX / OCX На практике этими словами часто обозначают в совокупности COM-компоненты и связанные с ними активы. В частности, сюда часто относят UI-элементы управления .ocx и компоненты, встраиваемые в IE или контейнеры
Зависимость от WebBrowser / IE Даже если это не сам ActiveX, сюда относятся встроенные браузеры и интеграции, построенные на модели IE. С точки зрения принятия решений это очень близкая проблема

Строго говоря, ActiveX и COM — не одно и то же. Но на практике проблемные точки у них весьма похожи.

  • Совпадают ли 32-бит / 64-бит
  • Как распространять регистрацию и зависимые DLL
  • В каком хосте / контейнере это работает
  • Не застрянете ли вы на STA, цикле сообщений, обратных вызовах
  • Не осталась ли зависимость от браузера

В этой статье мы рассматриваем такие практические точки принятия решений в комплексе.

Где на практике обычно застреваютСтрого говоря ActiveX и COM — не одно и то же, но точки, где обычно застревают, очень похожи: совпадение разрядности, регистрация и зависимые DLL, хост, предпосылки STA и callback, зависимость от браузера.Проект с ActiveX / OCXСовпадает ли bitnessРегистрация и распространение зависимых DLLВ каком хосте это работаетПредпосылки STA и callbackНе осталась ли зависимость от браузера

Рис. 2: ActiveX и COM строго говоря разные вещи, но на практике застревают примерно в одних и тех же местах.

Дальше по тексту постоянно встречаются сокращения, поэтому сведём их заранее. В главе 7 чек-лист говорит «выписать ProgID и CLSID» — без этой таблицы на этом шаге не сдвинуться.

Термин Как читать / официальное имя Смысл
CLSID Class ID GUID, однозначно указывающий реализацию (класс) COM-компонента. Регистрация в реестре тоже крутится вокруг этого значения
ProgID Programmatic Identifier Человекочитаемое имя, привязанное к CLSID. Строка вроде Excel.Application
IID Interface ID GUID, однозначно указывающий COM-интерфейс. Это не CLSID
TLB Type Library Файл с двоичной информацией о типах: интерфейсы, методы, аргументы. Именно поэтому VB6 и .NET могут вызывать компонент «с типами»
RegAsm Assembly Registration Tool Инструмент из .NET Framework. Регистрирует сборку .NET в реестре так, чтобы её можно было вызывать из COM
AxHost Базовый класс, чтобы хостить элемент ActiveX на Windows Forms
AxImp ActiveX Control Importer Инструмент, который из OCX генерирует обёрточную сборку для Windows Forms
in-proc / out-of-proc внутри процесса / вне процесса Работает в том же процессе, что вызывающий код (DLL или OCX), или в отдельном процессе (EXE-сервер)
LocalServer Форма, когда COM-сервер работает как EXE в отдельном процессе. Позволяет обойти стену разрядности и изолировать падения
Reg-Free COM / side-by-side COM без регистрации Механизм, который решает COM без записи в реестр — по сведениям в манифесте приложения
design-time / runtime лицензия на этапе разработки / на этапе выполнения У вендорских элементов управление лицензией при размещении на форме в IDE и при запуске у заказчика может быть раздельным
adapter / facade Проектный приём: мелкий существующий API заменить своим, более крупным и удобным
STA / MTA Single / Multi Threaded Apartment Потоковая модель COM. От неё зависит, с какого потока можно вызывать объект

3. Таблица решений, с которой стоит начать

3.1. Общая картина

Если начать с этой таблицы, общее направление, как правило, определяется сразу.

Ситуация Первый выбор Причина
Есть зависимость от ActiveX в браузере Склоняемся к замене Сам Edge ActiveX не поддерживает, а режим IE позиционируется как мера продления срока службы
OCX стабильно работает в настольном приложении, область изменений невелика Склоняемся к тому, чтобы оставить Стоимость слома сейчас часто выше
Хочется перевести на .NET только окружение, но поведение компонента непредсказуемо Склоняемся к обёртке Безопаснее сначала зафиксировать границу
Хотите поместить 32-битный OCX напрямую в 64-битный процесс Обернуть / изменить конфигурацию Это граница, которую нельзя пересечь in-proc
Используется только как UI-компонент, есть замена Склоняемся к замене Часто достаточно поверхностной замены
Вендор прекратил поддержку, постоянные проблемы с подписью, регистрацией, зависимыми DLL Склоняемся к замене Эксплуатационные издержки уже проявились как технический долг
Внутри — управление оборудованием, отчёты, собственный протокол Склоняемся к обёртке Пока поведение не зафиксировано, стоимость замены непредсказуема
ДаНетДаДаНетНетДаНетДаНетЕсть ActiveX / OCXЗависимость от браузера?Приоритет — заменарежим IE — мера продленияВ основном UI-компонент?Есть равноценная замена?Рассмотреть заменуСначала обернуть и зафиксировать границуЕсть управление оборудованием / своя спецификация / логика отчётов?Сначала обернутьсобрать тесты, затем заменять поэтапноБольно с регистрацией / разрядностью / распространением?Пересмотреть конфигурациюрассмотреть out-of-proc / связь через отдельный процесс / Reg-Free COMРешение оставить тоже реалистично

Рис. 3: Первое ветвление — есть ли зависимость от браузера; дальше направление задают «это UI-компонент?», «есть ли замена?» и «несёт ли он спецификацию?».

Далее рассмотрим каждый вариант по порядку.

3.2. Решение оставить

Сам по себе факт, что это ActiveX / OCX, ещё не делает его объектом замены. При соблюдении следующих условий оставить его как есть чаще всего действительно дешевле всего.

  • Область использования замкнута, а условия эксплуатации зафиксированы — внутреннее распространение, поставка вместе с оборудованием и тому подобное
  • Этот компонент до сих пор стабильно работает, и запросы на изменение невелики
  • Вендор всё ещё активен, либо компания может обеспечить хотя бы минимальную поддержку своими силами
  • Нет зависимости от браузера — всё замкнуто на существующем настольном хосте
  • Предпосылку о 32-бит / 64-бит пока менять не нужно

Здесь важно понимать: оставить — не значит забросить. Если вы оставляете компонент, стоит сделать как минимум следующее.

  • Задокументировать поддерживаемую ОС, разрядность, необходимые зависимые DLL и порядок регистрации
  • Перевести установку, регистрацию и удаление со «человеческих» заметок на скрипты или инсталлятор
  • Подготовить дымовой тест (smoke test) для чистого окружения
  • По возможности собрать все обращения к компоненту в одном месте, а не разбрасывать по всему приложению

Хуже всего — 10 лет подряд следовать принципу «работает — не трогай», пока никто уже не сможет объяснить исходные предпосылки. Чем чаще вы выбираете оставить компонент, тем важнее становится сделать эти предпосылки явными.

Решение оставить и обязательная фиксация предпосылокОставить — не значит забросить: в комплект входят документирование предпосылок, скрипты регистрации, дымовой тест на чистом окружении и сбор обращений в одном месте.Решение оставитьЗафиксировать предпосылки письменноПеревести регистрацию на скриптыПодготовить дымовой тестСобрать обращения в одном месте

Рис. 4: «Оставить» не равно «забросить». Чем чаще выбираете оставить, тем важнее сделать предпосылки явными.

3.3. Решение обернуть

На практике именно этот выбор отнимает больше всего работы.

«Обернуть» здесь означает изолировать ActiveX / OCX внутри узкой границы и представить его окружению как новый API или новый экранный компонент.

Это довольно эффективно. Причина в том, что если начать полную переработку на этапе, когда поведение старого компонента ещё не разгадано до конца, легко получить двойную нагрузку — раскопки спецификации и воспроизведение дефектов одновременно. Безопаснее сначала изолировать старый компонент и навести порядок только на границе.

Схема выбора «обернуть»ActiveX / OCX изолируют внутри узкой границы и снаружи показывают как новый API или экранный компонент, чтобы не начинать полную переработку, пока поведение ещё не разгадано, и не получить сразу раскопки спецификации и воспроизведение дефектов.ActiveX / OCXИзолировать внутри узкой границыПоказать как новый APIСнаружи виден только новый фасадИзбежать двойной нагрузки раскопок и воспроизведения

Рис. 5: «Обернуть» — это изоляция старого компонента и новый фасад снаружи; оно работает как этап перед полной переработкой.

У обёртки есть несколько устоявшихся форм.

Способ обёртки Подходит для На что обратить внимание
Хост на WinForms + AxHost / Aximp Встраивание в существующие настольные экраны, когда нужно оставить лишь несколько экранов STA, события, зависимости времени дизайна, лицензирование
32-битный вспомогательный EXE / COM LocalServer / связь через отдельный процесс Переход на 64-битную сторону, изоляция сбоев Межпроцессное взаимодействие, порядок запуска, мониторинг, развёртывание
COM-совместимый фасад на стороне .NET Обновление внутренней реализации при сохранении существующих вызывающих COM-кода IID / CLSID / TLB / способ регистрации / разрядность

Когда направление выбрано, полезно знать и первый шаг.

Способ обёртки Что делать сначала Подробная процедура
Хост на WinForms + AxHost В Visual Studio щёлкнуть панель элементов правой кнопкой → «Выбрать элементы» → вкладка «COM-компоненты» и выбрать нужный. Из командной строки — aximp Ловушки регистрации и bitness при разработке COM/OCX/ActiveX
32-битный вспомогательный EXE / LocalServer Зарегистрировать 32-битный EXE как COM-сервер и вызывать его с 64-битной стороны out-of-proc Пример моста COM для вызова 64-битной DLL из 32-битного приложения
Reg-Free COM В манифесте приложения описать file и comClass и решать COM без записи в реестр Что такое Reg-Free COM — механизм использования COM без регистрации
COM-совместимый фасад на стороне .NET Опубликовать сторону .NET как COM и при необходимости сгенерировать TLB через dscom Как использовать DLL на .NET 8 из VBA с типизацией — публикация COM и TLB через dscom

aximp запускают из Developer Command Prompt Visual Studio.

aximp C:\path\to\MyControl.ocx

На выходе получаются две сборки: runtime callable wrapper для COM-типов и обёртка для Windows Forms, производная от AxHost. Имена файлов берутся не из исходного имени файла, а из ProgID — это легко пропустить. В примере документации Microsoft из msdxm.ocx выходят MediaPlayer.dll и AxMediaPlayer.dll. В ссылки проекта добавляют вторую и кладут на форму AxMediaPlayer.

Что генерирует aximpЕсли передать aximp OCX, он генерирует runtime callable wrapper для COM-типов и обёртку Windows Forms, производную от AxHost; на форму кладут вторую. Имена файлов определяются ProgID, а не исходным именем файла.Исходный OCXЗапуск aximpОбёрточная DLL COM-типовОбёрточная DLL, производная от AxHostДобавить в ссылки и положить на формуИмена файлов берутся из ProgID

Рис. 6: aximp выдаёт две DLL; на форму кладут обёртку, производную от AxHost.

Для Reg-Free COM манифест приложения в минимальном виде выглядит так.

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="MyApp" version="1.0.0.0" />
  <file name="MyControl.ocx">
    <comClass
      clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
      threadingModel="Apartment"
      progid="MyCompany.MyControl.1" />
  </file>
</assembly>

В варианте LocalServer путь к EXE пишется в реестр в HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalServer32. EXE-серверы, собранные на ATL или MFC, часто умеют саморегистрироваться через MyServer.exe /regserver и /unregserver. Но представления реестра разделены по разрядности, поэтому 32-битный EXE регистрируется в 32-битном представлении реестра — это нужно держать в голове всегда.

Регистрация LocalServer и представления реестраВ варианте LocalServer путь к EXE пишется в LocalServer32 под CLSID; саморегистрация через /regserver обычна, но представления реестра разделены по разрядности, и 32-битный EXE попадает в 32-битное представление.32-бит64-битEXE-серверЗаписать путь в LocalServer32Разрядность EXE?Регистрация в 32-битном представленииРегистрация в 64-битном представлении

Рис. 7: Куда регистрируется LocalServer, задаёт представление реестра, разделённое по разрядности.

Особенно важно при обёртке не копировать старый API целиком, все 200 методов подряд. Если так сделать, вы просто перенесёте старые особенности прямо в новый код без изменений.

При обёртке заметно помогает учитывать следующее.

  • Использовать методы крупной гранулярности
  • Не давать экранному коду напрямую трогать OCX
  • Фиксировать на границе журналы, необходимые при сбое
  • Определить на границе ответственность за тайм-ауты, повторные попытки и преобразование исключений
  • Сделать так, чтобы будущую замену можно было подставить через тот же интерфейс

Иногда на новой стороне .NET хочется сохранить только входную точку COM. В этом случае реалистична конфигурация «обновляем содержимое, но сохраняем только COM-контракт». Однако ощущений эпохи .NET Framework, когда достаточно было «на всякий случай сделать RegAsm», может не хватить. Работу с современным COM host в .NET, TLB, разрядностью и Registry-Free COM лучше спроектировать заранее — потом будет проще. Пошагово это разобрано в статьях Как использовать DLL на .NET 8 из VBA с типизацией — публикация COM и TLB через dscom и Что такое Reg-Free COM — механизм использования COM без регистрации.

Ответственность, которую фиксируют на границеПри обёртке делают методы крупной гранулярности, не дают экранному коду трогать OCX напрямую, на границе фиксируют журналы, тайм-ауты и преобразование исключений и оставляют возможность подставить будущую замену через тот же интерфейс.Граница обёрткиМетоды крупной гранулярностиЖурналы на границеТайм-ауты и преобразование исключенийТа же точка входа для будущей заменыНе копировать 200 старых методов

Рис. 8: Ценность обёртки — собрать ответственность на границе; копирование старого API эту ценность снимает.

3.4. Решение заменить

Замена подходит главным образом для случаев, когда проблема — это поверхностное устаревание.

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

  • Этот ActiveX используется только как UI-компонент
  • Вендор выпустил преемника для .NET / WPF / WebView2
  • Тормозит зависимость от браузера или предпосылка про IE
  • Постоянные проблемы с регистрацией, подписью, правами администратора, настройками безопасности
  • Есть тесты или бизнес-сценарии, позволяющие проверить альтернативную реализацию

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

Если вы заменяете, начинайте с UI.

  • Сетки (grid)
  • Календари
  • Деревья
  • Область отображения браузера
  • Простые вспомогательные элементы ввода

Их сравнительно легко заменить. С другой стороны, встречаются и такие, что выглядят как UI, а внутри плотно набиты логикой.

  • ActiveX от вендора для управления оборудованием
  • Элементы управления, слитые с печатью или формированием отчётов
  • Элементы управления, инкапсулирующие чтение и запись собственного формата файлов
  • Элементы управления с COM-обратными вызовами или предпосылками о потоках

Ошибитесь в этом различии — и оценка трудозатрат рассыплется в одночасье.

Как отличить случай для заменыЕсли компонент используется только как UI и есть замена, менять сравнительно легко; если за внешним видом стоят управление оборудованием, отчёты, свой формат или предпосылки о потоках, сразу выбрасывать его обычно значит увязнуть.только поверхностное устареваниевнутри сидит спецификацияЧто стоит за внешним видомЗаменять сравнительно легкоСразу выбросить — увязнутьСначала решение обернуть

Рис. 9: Годится ли замена, решает различие «поверхностное устаревание» и «плотная начинка».

3.5. Зависимость от браузера рассматриваем отдельно

Это действительно отдельная категория.

У ActiveX в браузере, в отличие от настольного OCX, довольно слабые основания для дальнейшего развития.

Причина проста: современные браузерные платформы больше не делают это своим главным полем боя. Сам Microsoft Edge не поддерживает ActiveX. Режим IE, в свою очередь, использует движок семейства IE для настроенных сайтов и может служить слоем совместимости для запуска части функций IE, включая ActiveX.

Иными словами:

  • Продлить жизнь, чтобы оно работало сейчас, — можно
  • Но как долгосрочное проектное решение на это рассчитывать не стоит
Место ActiveX в браузереСам Microsoft Edge ActiveX не поддерживает; режим IE — слой совместимости, который для заданных сайтов использует движок семейства IE. Продлить жизнь сейчас можно, но как долгосрочное решение рассчитывать на это не стоит.ActiveX в браузереВ самом Edge не работаетРежим IE может продлить жизньДолгосрочно рассчитывать не стоитСмотреть на замену как на приоритет

Рис. 10: Для ActiveX в браузере разделяйте продление жизни и постоянное решение и смотрите на замену как на приоритет.

То же самое происходит и с элементом управления WebBrowser, встроенным в Windows-приложения. WebBrowser тянет модель IE, поэтому если нужно просто отображать HTML, для новой работы естественнее сделать первым кандидатом WebView2.

Однако здесь важно учитывать: WebView2 — не полная замена WebBrowser «один в один».

  • Скрипты, рассчитанные на DOM IE
  • Зависимости от ActiveX
  • Допущения вокруг window.external
  • Поведение, завязанное на зоны безопасности и интранет

Всё это напрямую не переносится. Если вы заменяете компонент, нужно заново спроектировать не только движок отрисовки, но и сам стык браузера с нативным кодом.

Что в WebView2 напрямую не переноситсяWebView2 — не полная замена элемента управления WebBrowser; скрипты, рассчитанные на DOM IE, зависимость от ActiveX, допущения вокруг window.external и поведение зон безопасности напрямую не переносятся.От WebBrowser к WebView2Если нужно только HTML — первый кандидатНапрямую не переноситсяСкрипты, рассчитанные на DOM IEЗависимость от ActiveXДопущения window.externalПоведение зон безопасности

Рис. 11: WebView2 может заменить движок отрисовки, но стык модели IE не наследует.

4. Моменты, которые легко сбивают с толку

4.1. UI-компонент или компонент со встроенной спецификацией

Это самое важное.

Для старой сетки или календаря достаточно проверить совместимость внешнего вида и событий — и разговор заметно продвигается. С другой стороны, у ActiveX с управлением оборудованием, отчётами или собственным форматом за внешним видом скрыта целая спецификация.

Хотя это выглядит как один и тот же «элемент управления на экране», на деле диапазон довольно широк.

  • Простой компонент отображения списка
  • Компонент, посылающий команды оборудованию по собственному протоколу
  • Компонент, который внутри самостоятельно занимается тайм-аутами, переподключением, повторной отправкой и поглощением исключений
  • Компонент, несущий на себе совместимость печати или форматов экспорта

Переписывать последний вариант заново с нуля — как правило, это превращается в проект по раскопке спецификации. Здесь безопаснее сначала обернуть компонент.

UI-компонент или компонент со встроенной спецификациейОдин и тот же «элемент на экране» может быть простой отображающей деталью или компонентом, который сам шлёт команды оборудованию, переподключается и держит совместимость отчётов; сразу переписывать второй — обычно проект раскопок спецификации.Элемент управления на экранеПросто отображающая детальКомпонент со встроенной спецификациейСовместимость внешнего вида уже двигает разговорСразу переписывать — раскопки спецификацииБезопаснее сначала обернуть

Рис. 12: Самое важное различие. Внешний вид может быть одним и тем же, а ход работы зависит от того, зашита ли за ним спецификация.

4.2. 32-бит / 64-бит и границы процессов

Это часто упускают из виду, хотя по сути это очень важный момент.

In-proc OCX должен совпадать по разрядности с процессом, который его загружает. То есть 32-битный OCX нельзя напрямую загрузить в 64-битное приложение.

Реалистичные варианты здесь, как правило, сводятся к трём.

  • Пока оставить хост-приложение тоже 32-битным
  • Изолировать OCX в отдельном 32-битном процессе и связать его с 64-битной стороной через IPC или out-of-proc COM
  • Заменять зависимость от этого OCX, начиная с тех мест, где это возможно

Расчёт «раз Any CPU, то как-нибудь само образуется» здесь обычно не работает. Даже если вы создаёте COM-совместимый фасад на новой стороне .NET, внешний вид managed-кода и фактическая разрядность COM host — это разные вопросы. Начните здесь небрежно — и получите неприятную ситуацию, когда сборка проходит, а на машине заказчика ничего не запускается.

Три варианта для 32-битного OCX и перехода на 64-бит32-битный OCX нельзя загрузить in-proc в 64-битный процесс, поэтому остаются три варианта: держать хост 32-битным, изолировать в отдельном 32-битном процессе и связать через IPC или out-of-proc COM, либо заменять зависимость там, где уже можно.32-битный OCX in-proc нельзяДержать хост 32-битнымИзолировать в отдельном 32-битном процессеЗаменять там, где уже можно снять зависимостьСвязь через IPC или out-of-proc COM

Рис. 13: Стену разрядности усилием воли не обойти; реалистичные варианты сходятся к этим трём.

4.3. Регистрация, распространение, права, лицензии

Технически компонент вызывается без проблем, а вот на этапе распространения всё умирает. Для ActiveX / OCX это довольно частая история.

Обычно проблемными местами становятся такие вещи.

  • Предпосылки для regsvr32 держатся только в чьей-то голове
  • Размещение зависимых DLL нигде явно не зафиксировано
  • Нужны права администратора, но это не отражено в порядке эксплуатации
  • У вендорского компонента разделены лицензии design-time и runtime
  • Работает на машине разработчика, но не работает в чистом окружении

Всё это способно остановить проект, даже если не тронуть ни строчки кода.

Конфигурации без регистрации или размещение side-by-side иногда облегчают ситуацию, но это не волшебный порошок — совместимость с контейнером и способом распространения всё равно нужно проверять.

Иными словами, миграция ActiveX / OCX — это не только реализация, но и проектирование распространения. Отложите этот момент на потом — и в конце вас ждёт эффектное падение.

Узкие места, на которых останавливает распространениеЧеловеческая зависимость от regsvr32, неявное размещение зависимых DLL, права администратора вне эксплуатационной процедуры и лицензии, разделённые на design-time и runtime, останавливают проект, даже если не тронуть ни строчки кода.Проектирование распространенияregsvr32 держится на людяхЗависимые DLL неявныПрава администратора вне процедурыЛицензия разделена надвоеОстанавливает, даже не трогая код

Рис. 14: Компонент технически вызывается, а умирает на распространении — это узкое место проектируют отдельно от реализации.

4.4. STA / цикл сообщений / обратные вызовы

ActiveX / OCX — это не просто вызов DLL. Он может нести предпосылки о потоковой модели COM и о цикле сообщений.

Особенно стоит насторожиться в таких случаях:

  • Стабильность обеспечивается только при работе в потоке UI
  • Компонент рассчитан на STA, но его небрежно вызывают со стороны MTA
  • Во время синхронного вызова возвращается обратный вызов (callback)
  • Неясно, в каком потоке должны приниматься события

Поначалу это проявляется как «иногда зависает», «иногда не приходят события». Но по сути это почти всегда нарушение предпосылок.

Поэтому и при обёртке, и при замене лучше заранее зафиксировать, в каком потоке создавать объект, из какого потока вызывать и где принимать события.

Сначала зафиксировать предпосылки о потокахЕсли заранее не зафиксировать, в каком потоке создавать объект, из какого вызывать и где принимать события, получите «иногда зависает / иногда нет событий» — типичное лицо нарушения предпосылок.Три пункта, которые фиксируют заранееВ каком потоке создаватьИз какого потока вызыватьГде принимать событияЕсли размыто — нарушение предпосылок под видом случайных сбоев

Рис. 15: За «иногда зависает» почти всегда стоит нарушение предпосылок; его предотвращают, заранее зафиксировав потоковые договорённости.

4.5. Есть ли тесты, можно ли наблюдать за поведением

Заменить компонент трудно не только потому, что код старый. Трудно потому, что нет критерия, по которому можно сказать «поведение осталось тем же».

Одно только наличие следующего сильно меняет дело.

  • Дымовые тесты для каждого сценария работы
  • Примеры входных и выходных данных
  • Снимки экрана или образцы отчётов
  • Шаблоны ошибок и ожидаемое поведение
  • Журналы на случай тайм-аута или отсутствия подключённого оборудования

Особенно когда задействовано оборудование или отчёты, случается странная вещь: реальное поведение оказывается более правдивым источником, чем спецификация. Без средств наблюдения замена превращается в раскопки.

Средства наблюдения держат заменуБез дымовых тестов, образцов ввода-вывода и отчётов, шаблонов ошибок и ожидаемого поведения нечем сказать «поведение осталось тем же», и замена превращается в раскопки.естьнетЕсть ли средства наблюденияМожно сказать, что поведение то жеЗамена превращается в раскопкиДымовые тесты, образцы и аналоги

Рис. 16: Трудность замены задаёт не столько возраст кода, сколько наличие средств наблюдения, по которым можно сказать «поведение то же».

5. Рекомендации по типовым сценариям

5.1. Внутреннее настольное приложение, которое до сих пор стабильно работает

Рекомендация — склоняться к тому, чтобы оставить.

При таких условиях часто лучше не отдирать компонент насильно.

  • Используется только внутри компании
  • Целевые устройства и ОС в достаточной мере зафиксированы
  • Этот OCX задействован лишь на нескольких экранах
  • Запросы на доработку невелики, срок жизни предсказуем

Тем не менее лучше не оставлять компонент как есть, без обёртки, а хотя бы собрать места вызова в одном месте — это окупится позже.

Иначе говоря, стратегия такая:

  • Сейчас — оставить
  • Но навести порядок хотя бы на границе
  • Сделать так, чтобы, когда потребуется замена, можно было начать именно отсюда

Такая трёхступенчатая структура выглядит естественно.

5.2. Хотите перенести 32-битный OCX на 64-битную сторону

Рекомендация — обернуть / изменить конфигурацию.

Идти здесь напрямую — тупик: 32-битный OCX нельзя загрузить in-proc в 64-битный процесс.

Реалистично управлять этим удобнее, изолировав компонент во вспомогательном 32-битном процессе или LocalServer и общаясь с 64-битным приложением через крупнозернистый API.

32-битный OCX32-битный хелпер / LocalServer64-битное .NET-приложение32-битный OCX32-битный хелпер / LocalServer64-битное .NET-приложениеЗапрос через крупнозернистый APIIn-proc вызовРезультат / событияПреобразованный результат

Рис. 17: 64-битное приложение вызывает OCX, изолированный в 32-битном хелпере, через крупнозернистый API.

Здесь важно не транслировать все мелкие методы напрямую один в один. Межпроцессная граница быстро становится болезненной, если прогонять через неё большой поток мелких вызовов.

  • Стремитесь к гранулярности примерно «1 операция = 1 запрос»
  • Приводите возвращаемые значения и ошибки к осмысленным единицам
  • Фиксируйте журналы на границе

При такой форме позже, когда потребуется по-настоящему заменить внутреннюю реализацию, это тоже будет проще.

Здесь, прежде чем сразу писать собственный вспомогательный EXE, есть ступень, которую стоит проверить.

Если этот OCX / DLL — in-proc COM-сервер, то есть его можно зарегистрировать через InprocServer32, то его можно поместить в суррогатный процесс, поставляемый с Windows, и выставить наружу как out-of-proc Local Server. Достаточно добавить к CLSID значение AppID и записать в соответствующий ключ AppID пустую строку DllSurrogate — своего кода при этом не нужно ни строки. Порядок регистрации собран в разделе 3.5 статьи Ловушки регистрации и bitness при разработке COM/OCX/ActiveX.

Однако суррогат не устраняет разницу в разрядности. Исчезает только ограничение «это должно находиться в одном процессе»: вызовы становятся out-of-proc, и стоимость маршалинга и межпроцессного взаимодействия ложится сверху как есть.

Что из этого выбрать, как правило, определяется этой таблицей.

Ситуация Что выбрать Причина
Объект автоматизации, работа с которым сводится к вызовам методов и событиям Сначала суррогат Потому что out-of-proc получается одной лишь регистрацией и писать код не нужно
Типы, которыми вы обмениваетесь, поддаются маршалингу через IDispatch или зарегистрированный proxy / stub Сначала суррогат Потому что средства для пересечения границы уже есть
У этого CLSID уже есть регистрация EXE вроде LocalServer32 Суррогату здесь делать нечего Потому что запуск EXE-сервера или службы всегда имеет приоритет
Нужен как визуальный элемент управления, который кладут на форму и заставляют рисовать Продумать другую конфигурацию Потому что окно предполагается находящимся внутри процесса хоста
Мелкие вызовы идут часто, и транслировать их напрямую тяжело Собственный вспомогательный EXE Потому что нужен свой слой, собирающий их в крупнозернистый API
Для собственного интерфейса нет маршалера Собственный вспомогательный EXE Потому что быстрее подготовить proxy / stub или самому определить типы на границе
Хочется самому держать в руках порядок инициализации, переподключение, тайм-ауты и журналы Собственный вспомогательный EXE Потому что временем жизни процесса суррогата распоряжается COM

Иначе говоря, суррогат — это минимальный ход, который стоит попробовать первым, а собственный EXE — ход на случай, когда границу хочется спроектировать самому. Строка таблицы из 3.1 «Хотите поместить 32-битный OCX напрямую в 64-битный процесс → обернуть / изменить конфигурацию» не меняется. Просто читайте её так, что внутри этого «обернуть» есть две ступени.

5.3. Экраны, завязанные на IE / WebBrowser

Рекомендация — приоритет замены.

Это область, где «работает сейчас» и «легко поддерживать в дальнейшем» плохо совпадают. Режим IE сильно помогает с совместимостью, но предпосылка всё равно остаётся связанной с семейством IE.

Поэтому удобно разделить подход так:

  • Продлевать жизнь через режим IE, чтобы не останавливать внутренние процессы
  • При этом не путать продление жизни с постоянным решением
  • Выбирать замену из WebView2, чистого веба, гибрида нативного UI и веба и подобных вариантов

Зафиксируем и конкретные меры на стороне продления. Режим IE не включается «сам, если поставить Edge»: сайт открывается движком семейства IE только после того, как его задали политикой. Входов в настройку три.

Способ Настройка Дополнение
Перечислить сайты В групповой политике Microsoft Edge 78 и новее «Configure the Enterprise Mode Site List» указать расположение XML со списком сайтов корпоративного режима Базовая форма
Переиспользовать список со стороны старого IE Политика Internet Explorer «Use the Enterprise Mode IE website list» Если задана политика стороны Edge, она имеет приоритет
Отправить весь интранет Включить групповую политику Microsoft Edge 77 и новее «Send all intranet sites to Internet Explorer» Охват широкий, инвентаризацию это не заменяет

Предпосылки: на Windows и Edge стоят свежие обновления, установлены административные шаблоны Microsoft Edge, в компонентах Windows включён Internet Explorer 11. Если чего-то из этого нет, режим IE не заработает.

В режиме IE работают элементы ActiveX и Browser Helper Object. То есть продление жизни действительно возможно. Именно поэтому, если пользоваться им без условия выхода, из него потом не выбраться. Как снимать зависимость, разобрано в статье Как избавиться от зависимости внутренних веб-систем от режима IE.

Как мыслить продление через режим IEРежим IE начинает работать только после того, как сайты заданы политикой, и ActiveX в нём действительно работает; именно поэтому его нужно использовать вместе с условием выхода, не путая продление жизни с постоянным решением.Задать целевые сайты политикойОткрывается в режиме IEМожно продлить жизнь, включая ActiveXПользоваться вместе с условием выходаБез условия потом не выбраться

Рис. 18: Режим IE продлевает жизнь именно потому, что «действительно работает» — поэтому его используют только вместе с условием выхода.

Особенно если элемент управления WebBrowser используется просто как HTML-вьюер, приоритет замены высокий.

С другой стороны, если ActiveX внутри браузера выполняет ещё и роли вроде работы с локальными файлами, оборудованием, подписью или собственными надстройками, это уже не замена движка отрисовки, а переработка нативной интеграции. Здесь разговор становится немного тяжелее.

5.4. ActiveX с управлением оборудованием или собственной спецификацией

Рекомендация — сначала обернуть.

Этот тип содержательнее, чем кажется по внешнему виду. Даже если документация SDK скудная, за годы работы в реальных условиях в компоненте могло неявно накопиться поведение вроде такого:

  • Как он ждёт при неудачном подключении
  • Повторные попытки после тайм-аута
  • Порядок событий
  • Обходные пути, поглощающие особенности реального оборудования
  • Интерпретация исключений и кодов ошибок

Если переписывать такой компонент заново, руководствуясь принципом «он всё равно старый», с высокой вероятностью загорятся полевые испытания.

Поэтому безопаснее начинать именно отсюда.

  1. Изолировать существующий компонент внутри границы
  2. Добавить журналирование, чтобы было видно, что происходит
  3. Собрать тестовые сценарии и шаблоны поведения реального оборудования
  4. И только затем выделить те участки, которые можно заменить

Это не эффектно, но на практике именно это работает лучше всего.

Как идти с ActiveX, который несёт спецификациюСначала изолировать существующий компонент внутри границы, добавить журналирование, чтобы было видно, что происходит, собрать тестовые сценарии и шаблоны реального оборудования и только потом выделять участки, которые можно заменить.Изолировать внутри границыДобавить журналирование и сделать поведение видимымСобрать сценарии и шаблоны реального оборудованияВыделить участки, которые можно заменить

Рис. 19: Для компонента с управлением оборудованием или собственной спецификацией этот порядок снижает риск, что полевые испытания вспыхнут.

6. Частые антипаттерны

Антипаттерн В чём боль Первый шаг к исправлению
Полная переработка только потому, что есть ActiveX Легко упустить часть спецификации и получить взрыв трудозатрат Сначала инвентаризация и выделение границ
Попытка напрямую поместить 32-битный OCX в 64-битное приложение Принципиально невозможно Изолировать на 32-битной стороне или изменить конфигурацию
Прямые вызовы API компонента из экранного кода Легко становится невозможно заменить Свести к адаптеру / фасаду
Ручная эксплуатация процедуры regsvr32 Различия окружений вызывают сбои каждый раз Рассмотреть инсталлятор, скрипты, манифесты
Успокоенность из-за наличия режима IE Легко перепутать продление жизни с постоянным решением Определить план замены и условия завершения
Поведение не зафиксировано перед заменой Невозможно судить о завершённости Подготовить дымовые тесты, тестовые данные, журналы

Из них на практике особенно часто встречаются три.

  1. Спешка с полной переработкой
  2. Недооценка барьера разрядности
  3. Разбрасывание API по всему приложению

Избегая этих трёх пунктов, вы уже заметно снижаете вероятность сбоев.

Три антипаттерна, которые видят чаще всегоВероятность сбоев уже заметно падает, если не спешить с полной переработкой, не недооценивать стену разрядности и не разбрасывать API компонента по всему приложению.Спешка с полной переработкойИзбегать этих трёхНедооценка стены разрядностиРазбрасывание API по всему приложениюВероятность сбоев заметно падает

Рис. 20: Среди антипаттернов эти три встречаются чаще всего; избегать их уже даёт большой эффект.

7. Чек-лист для начала миграции

Проекты с ActiveX / OCX идут лучше, если сначала провести инвентаризацию, а не сразу бросаться в реализацию. Порядок примерно такой.

  1. Составить перечень используемых OCX / DLL
    • Имя файла, версия, ProgID, CLSID, вендор, наличие лицензии
  2. Выяснить, где они используются
    • Экраны, функции, отчёты, оборудование, пакетные задания, интеграция с Office и так далее
  3. Проверить разрядность и условия хоста
    • 32-бит / 64-бит, in-proc / out-of-proc, предпосылка STA, зависимость от браузера
  4. Проверить условия распространения
    • Способ регистрации, зависимые DLL, права администратора, тихая установка, воспроизведение в чистом окружении
  5. Создать дымовые тесты
    • Не только штатный сценарий, но и сбои, отсутствие подключения, тайм-ауты
  6. Построить границу
    • Адаптер, сервис, фасад, связь через отдельный процесс и так далее
  7. Опробовать на малых единицах — один экран, одна функция, одно устройство
  8. Расширять от границ, которые сработали, постепенно применяя оставить / обернуть / заменить

Пропустите эти шаги — и потом будет сложно объяснить даже то, что именно оказалось трудным.

8. Краткая шпаргалка по выбору

Ситуация Первый выбор
Стабильно работает только внутри компании, изменения невелики Оставить
Хочется перевести на .NET только окружение Обернуть
Сталкиваются 32-бит / 64-бит Обернуть / изменить конфигурацию
Зависимость от IE / WebBrowser / ActiveX в браузере Заменить
Простой UI-компонент, есть замена Заменить
Несёт управление оборудованием, отчёты, собственную спецификацию Обернуть
Постоянные проблемы с регистрацией или распространением Обернуть или заменить

Если сомневаетесь, для начала определите, UI-компонент это или граница со встроенной спецификацией, — так вы вряд ли ошибётесь.

9. Итог

Как поступать с ActiveX / OCX — это не вопрос, который решается фразой «это легаси, поэтому плохо».

Есть четыре момента, на которые стоит смотреть в первую очередь.

  1. Это простой UI-компонент или граница со встроенной спецификацией
  2. Обязательно ли использовать его в том же процессе
  3. Не застрянете ли вы на 32-бит / 64-бит, регистрации, зависимости от браузера или лицензировании
  4. Можно ли наблюдать за поведением до замены

Когда эти четыре момента прояснены, картина обычно складывается так:

  • Стабильно работает, срок жизни предсказуем — оставить
  • Хочется модернизировать только окружение — обернуть
  • UI-компонент или зависимость от браузера — заменить
  • Компонент со встроенной спецификацией — сначала обернуть, затем заменять поэтапно

Устаревшая технология — не повод для насмешек, а действующий объект, в котором сжаты история и контракты. Но чтобы жить с этим объектом дальше, необходимо проектирование границ.

Когда вы научитесь совмещать в своём мышлении «оставить, обернуть, заменить», проекты с ActiveX / OCX внезапно превращаются в решаемую задачу.

Сводка итогаЕсли компонент стабильно работает и срок жизни предсказуем — оставить; если модернизируете только окружение — обернуть; UI-компонент или зависимость от браузера — заменить; компонент со встроенной спецификацией — сначала обернуть, затем заменять поэтапно.Как поступать с ActiveX / OCXСтабильная работа — оставитьМодернизация окружения — обернутьUI или зависимость от браузера — заменитьВстроенная спецификация — обернуть и заменять поэтапно

Рис. 21: Когда четыре контрольные точки ясны, «оставить / обернуть / заменить» складывается в эту форму.

10. С какими вопросами к нам обращаться

Эта тема часто приносит пользу уже на этапе прояснения направления, ещё до начала самой разработки.

Например, к нам хорошо подходят такие запросы:

  • Хотите провести инвентаризацию и понять, какие OCX действительно нужно заменить
  • Хотите заранее разобраться только с узкими местами 32-бит / 64-бит
  • Хотите перейти на .NET, но сохранить только входную точку COM
  • Хотите сравнить меры продления жизни и стратегию отступления для ActiveX, поддержку которого прекратил вендор
  • Хотите увидеть, с какого места можно начать отделять зависимость от IE / WebBrowser
  • Хотите для начала безопасно выделить только один экран или одну функцию

В проектах с ActiveX / OCX исход часто решает не реализация, а то, как провести границы. Даже начать с оценки текущего состояния, сравнения конфигураций и проектирования порядка миграции как предварительный этап перед полной переработкой — уже вполне осмысленно.

11. Источники

  • Microsoft Learn: AxHost Class (System.Windows.Forms)
    • https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.axhost
  • Microsoft Learn: Aximp.exe (Windows Forms ActiveX Control Importer)
    • https://learn.microsoft.com/ja-jp/dotnet/framework/tools/aximp-exe-windows-forms-activex-control-importer
  • Microsoft Learn: How to: Add ActiveX Controls to Windows Forms
    • https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-add-activex-controls-to-windows-forms
  • Microsoft Learn: Expose .NET Core components to COM
    • https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
  • Microsoft Learn: Registration-Free COM Interop
    • https://learn.microsoft.com/en-us/dotnet/framework/interop/registration-free-com-interop
  • Microsoft Learn: DllSurrogate
    • https://learn.microsoft.com/en-us/windows/win32/com/dllsurrogate
  • Microsoft Learn: Registering the DLL Server for Surrogate Activation
    • https://learn.microsoft.com/en-us/windows/win32/com/registering-the-dll-server-for-surrogate-activation
  • Microsoft Learn: Frequently Asked Questions about Microsoft Edge
    • https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-frequently-asked-questions
  • Microsoft Learn: What is Internet Explorer (IE) mode?
    • https://learn.microsoft.com/en-us/deployedge/edge-ie-mode
  • Microsoft Learn: WebBrowser Class (System.Windows.Forms)
    • https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.webbrowser
  • Microsoft Learn: Introduction to Microsoft Edge WebView2
    • https://learn.microsoft.com/en-us/microsoft-edge/webview2/
  • KomuraSoft Blog: Основы COM STA/MTA — модели потоков и как избежать зависаний
    • https://comcomponent.com/ru/blog/2026/01/31/000-sta-mta-com-relationship/
  • KomuraSoft Blog: Вызов нативных DLL из C#: обёртка на C++/CLI или P/Invoke
    • https://comcomponent.com/ru/blog/2026/03/07/000-cpp-cli-wrapper-for-native-dlls/
  • KomuraSoft Blog: Пример моста COM для вызова 64-битной DLL из 32-битного приложения
    • https://comcomponent.com/ru/blog/2026/01/25/002-com-case-study-32bit-to-64bit/
  • KomuraSoft Blog: Что такое COM / ActiveX / OCX - объясняем различия и связь между ними
    • https://comcomponent.com/ru/blog/2026/03/13/000-what-is-com-activex-ocx/
  • KomuraSoft Blog: Как использовать DLL на .NET 8 из VBA с типизацией — публикация COM и TLB через dscom
    • https://comcomponent.com/ru/blog/2026/03/16/007-dotnet8-dll-typed-vba-com-dscom-tlb/
  • KomuraSoft Blog: Что такое Reg-Free COM — механизм использования COM без регистрации
    • https://comcomponent.com/ru/blog/2026/03/16/011-what-is-reg-free-com/
  • KomuraSoft Blog: Ловушки регистрации и bitness при разработке COM/OCX/ActiveX
    • https://comcomponent.com/ru/blog/2026/04/15/001-com-ocx-activex-pitfalls-visual-studio-bitness-admin-rights/
  • KomuraSoft Blog: Как избавиться от зависимости внутренних веб-систем от режима IE
    • https://comcomponent.com/ru/blog/2026/04/25/003-ie-mode-internal-web-system-life-extension-and-exit/
  • KomuraSoft Blog: После IE-режима — WebView2? Ограничение по ActiveX и реалистичный план миграции
    • https://comcomponent.com/ru/blog/webview2-embed-web-ui-in-windows-apps/

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

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

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

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

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

Нужно ли заменять ActiveX / OCX?
Смотрите не на «старое это или нет», а на то, что компонент на себя взял. Простой UI-компонент при наличии замены — заменяйте; если внутри управление оборудованием, отчёты или свой формат файлов — сначала оберните и зафиксируйте границу; если он стабильно работает и область изменений невелика, оставить как есть тоже реалистично. И «на всякий случай переписать всё», и «заморозить навсегда из страха» — оба варианта с высокой вероятностью сбоев.
Можно ли использовать 32-битный OCX из 64-битного приложения?
In-proc — нет. OCX должен совпадать по разрядности с процессом, который его загружает, и это принципиальное ограничение. Реалистичные варианты три: пока оставить хост-приложение тоже 32-битным; изолировать OCX в отдельном 32-битном процессе (вспомогательный EXE или COM LocalServer) и связать с 64-битной стороной через IPC или out-of-proc COM; либо заменять зависимость от OCX там, где это уже можно.
Что делать с зависимостью от ActiveX в браузере?
Здесь разумнее смотреть на замену как на приоритет. Сам Microsoft Edge ActiveX не поддерживает, а режим IE позиционируется как мера продления срока службы. Элемент управления WebBrowser точно так же тянет модель IE, поэтому если нужно просто показывать HTML, первым кандидатом становится WebView2. Но WebView2 — не полная замена «один в один»: скрипты, рассчитанные на DOM IE, и допущения вокруг window.external напрямую не переносятся.
Что конкретно значит «обернуть» ActiveX / OCX?
Изолировать ActiveX / OCX внутри узкой границы и снаружи показать его как новый API или новый экранный компонент. Устоявшиеся формы: хост на WinForms + AxHost, связь через отдельный процесс с помощью 32-битного вспомогательного EXE или LocalServer, COM-совместимый фасад на стороне .NET. При обёртке не копируйте старый API целиком — делайте методы крупной гранулярности, на границе закрепите ответственность за журналирование, тайм-ауты и преобразование исключений и сделайте так, чтобы будущую замену можно было подставить через тот же интерфейс.

Об авторе

Страница с профилем автора статьи.

Го Комура

Представитель KomuraSoft LLC

Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

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

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