Старый ЭЛТ-монитор и современный ноутбук, связанные световым потоком: перенос приложения между эпохами

Миграция VB6 на .NET: конвертеры, поэтапный переход через COM и замена OCX

РубрикаМиграцияУровеньСредний Чтение12 минОпубликовано ТегиVB6.NETCOMМиграция

Приложения на Visual Basic 6 переживают уже третье поколение Windows, но с каждым годом поддерживать их дороже. Разбираем, как перенести VB6-систему на .NET без остановки бизнеса: от инвентаризации до вывода старого кода из эксплуатации.

Главное. Миграция VB6 на .NET лучше всего проходит поэтапно: сначала инвентаризация зависимостей, затем автоматическая конвертация логики коммерческим инструментом (VBUC, VB Migration Partner или gmStudio) и перенос модулей по одному через COM-мост, а проверка идёт сравнением с эталонными результатами старой версии.

Встроенного конвертера у Microsoft больше нет, а .NET Upgrade Assistant с кодом VB6 не работает, поэтому основная работа ложится на команду. Если своих рук не хватает, анализ и поэтапный перенос legacy-систем можно отдать профильному подрядчику: рефакторингом и модернизацией старого кода, в том числе переносом десктопных приложений на .NET и в веб, занимается, например, YuSMP Group. Ниже — порядок работ, который подходит и для своей команды, и для работы с подрядчиком.

Почему VB6-приложение пора переносить именно сейчас?

Короткий ответ: сам VB6 не сломается завтра, но всё вокруг него постепенно становится несовместимым. Среда выполнения msvbvm60.dll по-прежнему поставляется с Windows и поддерживается по официальной политике поддержки Visual Basic 6, а вот среда разработки не поддерживается с 2008 года, сторонние OCX брошены вендорами, VBScript выключается, а новые драйверы СУБД выходят только в 64-битных версиях.

На практике повод для миграции почти всегда приземлённый. Ушёл последний разработчик, который умел собирать проект. Новый банк-партнёр требует TLS 1.3 и современный API. Нужен веб-интерфейс или мобильный клиент. Аудитор безопасности отказывается подписывать акт с компонентами без обновлений. Как держать приложение на плаву, пока решение не принято, мы разбирали в статье о сопровождении VB6 в 2026 году. Здесь речь о том, как уходить.

Целевая платформа сегодня одна: современный .NET. В октябре 2026 года это .NET 10 с долгосрочной поддержкой до ноября 2028 года, а у .NET 8 поддержка заканчивается 10 ноября 2026 года. Сверяйтесь с политикой поддержки .NET: начинать новый проект на версии, которая через месяц выйдет из поддержки, нет смысла.

Какие есть стратегии миграции VB6?

Вариантов четыре, и выбор между ними важнее выбора конвертера. Ошибка в стратегии стоит месяцев, ошибка в инструменте стоит недель.

  • Автоматическая конвертация целиком. Коммерческий конвертер переводит весь проект в VB.NET или C#, команда доводит результат до компиляции и проходит тесты. Подходит для монолитов на 50–500 тысяч строк, где бизнес-логика ценна, а архитектура в целом терпима. Результат работает, но остаётся «VB6 на .NET»: формы, глобальные модули, логика в обработчиках кнопок.
  • Поэтапный перенос через COM. Новое пишется на .NET и подключается к работающему VB6-приложению как COM-компонент. Модули переезжают по одному, пользователи не замечают переходов. Самый безопасный путь для систем, которые нельзя остановить.
  • Переписывание с нуля. Оправдано, если приложение маленькое, логика хорошо описана или старая архитектура не подходит под новые требования (веб, мобильные клиенты, многопользовательский режим). Главный риск: забытые правила, зашитые в код за двадцать лет.
  • Совместимый компилятор. twinBASIC открывает проекты VB6 и умеет собирать 64-битный код. Это продление жизни кодовой базы без смены языка, а не миграция в экосистему .NET; зрелость инструмента нужно проверять на своём проекте.

Часто стратегии комбинируют: бизнес-логику конвертируют автоматически и выносят в библиотеку, а интерфейс переписывают заново, сразу под веб. Такую гибридную схему проще всего вести через COM-мост, о котором ниже.

Шаг 1. Инвентаризация: что на самом деле внутри проекта

Число строк кода плохо предсказывает трудоёмкость. Гораздо важнее зависимости. Прежде чем запускать конвертер, соберите список:

  1. все проекты группы (.vbg), EXE, ActiveX DLL и OCX собственной разработки и связи между ними;
  2. сторонние OCX и DLL с версиями и вендорами: MSFlexGrid, Sheridan, ComponentOne, Crystal Reports, Winsock, MSComm и прочие;
  3. доступ к данным: DAO, RDO, ADO, прямые вызовы ODBC, строки подключения и хранимые процедуры;
  4. вызовы Win32 API через Declare, особенно с указателями, структурами и обратными вызовами;
  5. позднее связывание через CreateObject и переменные As Object: автоматика их почти не понимает;
  6. печать через объект Printer, работу с файлами через Open/Print #/Get #, использование реестра и INI;
  7. интеграции: обмен файлами, COM-автоматизация Excel и Word, внешние программы, которые вызывают ваши DLL.

Для каждой строки отметьте, есть ли у компонента аналог в .NET и кто будет его заменять. Эта таблица и есть реальная оценка проекта. Если в коде есть VB.NET-части, пригодится наш чек-лист аудита legacy-кода.

Шаг 2. Какой инструмент выбрать для конвертации кода?

Встроенного решения у Microsoft больше нет. Мастер обновления VB6 (Upgrade Wizard) поставлялся с Visual Studio 2002–2008 и был удалён в Visual Studio 2010. Его результат и тогда требовал много ручной работы, а целевой платформой был .NET Framework 2.0–3.5. .NET Upgrade Assistant часто называют преемником, но он работает только с проектами .NET Framework и код VB6 не читает. Его роль начинается позже: им удобно поднимать уже сконвертированный проект на современный .NET.

На рынке остались три коммерческих конвертера, которые реально используют на крупных проектах:

  • Visual Basic Upgrade Companion (VBUC) от Mobilize.Net. Генерирует C# или VB.NET без собственной библиотеки времени выполнения, умеет целиться в современный .NET, заменяет популярные OCX на аналоги WinForms. Хорош, когда нужен «чистый» результат без зависимостей.
  • VB Migration Partner от Code Architects. Делает ставку на максимальную совместимость: поставляет библиотеку, которая эмулирует поведение VB6 (массивы с ненулевой нижней границей, массивы контролов, Variant). Код компилируется быстрее, но зависит от этой библиотеки.
  • gmStudio от Great Migrations. Скорее среда реинжиниринга: правила перевода настраиваются под проект, конвертацию прогоняют многократно, пока результат не устроит. Подходит для больших портфелей приложений.

Почти все вендоры дают оценочный прогон на вашем коде. Используйте его: отчёт об ошибках конвертации на реальном проекте точнее любых маркетинговых процентов. Генеративные ассистенты в IDE помогают дочищать отдельные функции, но не заменяют конвертер на проекте в сотни форм.

Шаг 3. VB.NET или C#: на каком языке продолжать?

Visual Basic в современном .NET поддерживается: WinForms-проекты на VB.NET собираются под .NET 10, дизайнер работает, пространство My доступно. При этом Microsoft с 2020 года не развивает язык новыми возможностями, а новые библиотеки и примеры выходят в первую очередь на C#.

  • VB.NET выбирают, если команда из VB6-разработчиков, бюджет ограничен, а приложение после миграции будут в основном сопровождать. Сконвертированный код читается ближе к оригиналу, меньше рисков на этапе сверки.
  • C# выбирают, если систему будут активно развивать, нанимать новых людей, переносить часть логики в веб-API или мобильные клиенты. Разница в стоимости конвертации небольшая: инструменты генерируют оба языка.

Если вы уже идёте через VB.NET, загляните в разбор переноса WinForms на VB.NET в современный .NET: там описано, что ломается при переходе с .NET Framework и как это обходить.

Что ломается при переводе кода VB6 в .NET?

Различия в языке конвертеры закрывают хорошо, но их полезно знать, чтобы понимать отчёт об ошибках и правильно проверять результат.

  • Размеры типов. Integer в VB6 16-битный и становится Short, Long 32-битный и становится Integer, Currency переходит в Decimal. Любой код, который пишет структуры в файлы или передаёт их в API, нужно проверить побайтно.
  • Variant и позднее связывание. Variant становится Object, неявные преобразования перестают работать или работают иначе. Код вида obj.Method на переменной As Object в C# требует dynamic или явного интерфейса.
  • Массивы. Нижняя граница в .NET всегда 0: конструкции Dim a(1 To 10) и Option Base 1 переписываются вручную или эмулируются библиотекой.
  • ByRef по умолчанию. В VB6 параметры передаются по ссылке, если не указано иное, в VB.NET по значению. Функции, которые меняли аргументы, молча перестают это делать.
  • Обработка ошибок. On Error GoTo и Resume Next в VB.NET остались, в C# их нет. Блоки с Resume Next приходится раскладывать в Try/Catch вокруг каждой операции.
  • Формы и контролы. Массивы контролов, свойство Index, DoEvents, объект Printer, Line и Circle на форме, перетаскивание и OLE-контейнер. Это основная ручная работа после любой конвертации.
  • Строки фиксированной длины и Get/Put. Двоичные файлы старого формата читаются иначе. Оставьте эталонные файлы и сравнивайте результат чтения.
Пример.vbVB6 → VB.NET
' VB6
Dim total As Long
Dim items(1 To 10) As Integer
Private Sub AddItem(qty As Integer)   ' ByRef по умолчанию
    qty = qty + 1
End Sub

' VB.NET после конвертации
Dim total As Integer                  ' Long VB6 = 32 бита = Integer .NET
Dim items(10) As Short                ' индексы 0..10, элемент 0 не используется
Private Sub AddItem(ByRef qty As Short)
    qty += 1
End Sub
Самые неприятные ошибки после конвертации не те, что мешают компиляции, а те, что меняют результат молча: ByRef, округление Currency, сравнение дат и строк. Их ловят только тесты на эталонных данных.

Шаг 4. Как переносить по частям через COM-мост

COM-взаимодействие работает в обе стороны, и на этом построен поэтапный перенос. VB6 может вызывать .NET-код, если .NET-класс выставлен как COM-сервер. .NET-приложение может использовать старые ActiveX DLL через interop-сборку. Это позволяет менять систему изнутри, не останавливая её.

  1. Выделите модуль с чёткой границей: расчёт тарифов, генерация документов, обмен с внешней системой. Опишите его интерфейс.
  2. Напишите реализацию на .NET с тем же интерфейсом и пометьте класс атрибутами ComVisible и Guid. Для современного .NET включите COM-хостинг (EnableComHosting): сборка даст файл *.comhost.dll, который регистрируется через regsvr32 из SysWOW64, потому что процесс VB6 32-битный. Подробности в документации Microsoft по COM-компонентам .NET.
  3. Для раннего связывания VB6 нужна библиотека типов. В современном .NET она не генерируется автоматически: подготовьте .idl, соберите .tlb и встройте его в comhost. Без библиотеки типов VB6 работает через CreateObject и позднее связывание.
  4. Подключите новый компонент в VB6 вместо старого кода, прогоните сравнительные тесты, выкатите.
  5. Повторяйте, пока в VB6 не останутся только формы. Затем заменяйте интерфейс: на WinForms, если важна скорость перехода, или на веб, если пользователей нужно вывести из десктопа.

Сборка .NET-компонента должна быть 32-битной (x86), иначе процесс VB6 её не загрузит. Если команде проще, на переходный период мост можно собирать и под .NET Framework 4.8 с регистрацией через regasm /tlb: путь старый, но с VB6 работает без сюрпризов.

Шаг 5. Тестирование и вывод из эксплуатации

У VB6-приложений почти никогда нет автотестов, поэтому главный инструмент проверки здесь сравнение. Перед стартом снимите эталоны: выходные файлы, отчёты, содержимое таблиц после типовых операций на копии рабочей базы. После каждого этапа те же сценарии прогоняются на новой версии, результаты сравниваются автоматически.

  • Характеризационные тесты на перенесённую логику: фиксируют текущее поведение, даже если оно кажется странным. Как их писать, разобрано в статье о тестах для legacy VB.NET.
  • Параллельная работа. Несколько недель старая и новая версии обрабатывают одни и те же данные, расхождения разбираются по одному.
  • Отчёты и печатные формы сверяются отдельно: это самая заметная для пользователей часть. Замену Crystal Reports разбирали в отдельном материале.
  • Развёртывание. Регистрация COM, права на каталоги, 32-битные драйверы. Сценарий установки пишется заранее и проверяется на чистой машине.

Вывод VB6 из эксплуатации стоит планировать как отдельный этап с датой: убрать регистрацию компонентов, удалить старые установщики, заархивировать сборочную машину вместе с исходниками на случай расследований.

Как это делают сегодня

Типовой проект 2026 года выглядит так: инвентаризация и оценочный прогон конвертера, автоматический перевод бизнес-логики в библиотеку на C# или VB.NET под .NET 10, COM-мост для постепенной замены модулей в работающем приложении, затем новый интерфейс на WinForms, Blazor или как отдельное веб-приложение. Переписывание с нуля выбирают для небольших утилит и там, где старая логика хорошо задокументирована.

Вопросы и ответы

Можно ли автоматически конвертировать VB6 в .NET?

Частично. Коммерческие конвертеры VBUC, VB Migration Partner и gmStudio переносят формы, модули и классы и обычно закрывают большую часть синтаксиса. Сторонние OCX, работу с печатью, позднее связывание и Win32 API всё равно дорабатывают руками, поэтому после конвертации нужен полноценный цикл тестирования.

Что выбрать: VB.NET или C#?

VB.NET проще для команды, которая знает VB6, и ближе к исходному коду после конвертации. Язык поддерживается в .NET 10, но новых возможностей почти не получает. C# даёт больший рынок разработчиков и библиотек. Если систему будут развивать ещё много лет, чаще выбирают C#.

Подходит ли .NET Upgrade Assistant для VB6?

Нет. Upgrade Assistant обновляет проекты .NET Framework до современного .NET. Код VB6 он не читает. Мастер обновления VB6 был в Visual Studio до версии 2008 включительно и затем удалён.

Можно ли переносить приложение по частям?

Да, и это самый безопасный путь. Новый код на .NET оформляют как COM-видимые компоненты и вызывают из VB6, либо, наоборот, подключают старые ActiveX DLL к новому .NET-приложению через interop. Модули переносят по одному, пока VB6-часть не превратится в тонкую оболочку.

Сколько длится миграция VB6-приложения?

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

Что делать с отчётами Crystal Reports?

Их переносят отдельным потоком работ: инвентаризация .rpt-файлов, выбор замены (RDLC, SSRS, сторонние генераторы или отчёты кодом) и сверка печатных форм на эталонных данных.

Читайте также