
Миграция VB6 на .NET: конвертеры, поэтапный переход через COM и замена OCX
Приложения на Visual Basic 6 переживают уже третье поколение Windows, но с каждым годом поддерживать их дороже. Разбираем, как перенести VB6-систему на .NET без остановки бизнеса: от инвентаризации до вывода старого кода из эксплуатации.
Встроенного конвертера у 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. Инвентаризация: что на самом деле внутри проекта
Число строк кода плохо предсказывает трудоёмкость. Гораздо важнее зависимости. Прежде чем запускать конвертер, соберите список:
- все проекты группы (.vbg), EXE, ActiveX DLL и OCX собственной разработки и связи между ними;
- сторонние OCX и DLL с версиями и вендорами: MSFlexGrid, Sheridan, ComponentOne, Crystal Reports, Winsock, MSComm и прочие;
- доступ к данным: DAO, RDO, ADO, прямые вызовы ODBC, строки подключения и хранимые процедуры;
- вызовы Win32 API через Declare, особенно с указателями, структурами и обратными вызовами;
- позднее связывание через CreateObject и переменные As Object: автоматика их почти не понимает;
- печать через объект Printer, работу с файлами через Open/Print #/Get #, использование реестра и INI;
- интеграции: обмен файлами, 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. Двоичные файлы старого формата читаются иначе. Оставьте эталонные файлы и сравнивайте результат чтения.
' 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Шаг 4. Как переносить по частям через COM-мост
COM-взаимодействие работает в обе стороны, и на этом построен поэтапный перенос. VB6 может вызывать .NET-код, если .NET-класс выставлен как COM-сервер. .NET-приложение может использовать старые ActiveX DLL через interop-сборку. Это позволяет менять систему изнутри, не останавливая её.
- Выделите модуль с чёткой границей: расчёт тарифов, генерация документов, обмен с внешней системой. Опишите его интерфейс.
- Напишите реализацию на .NET с тем же интерфейсом и пометьте класс атрибутами ComVisible и Guid. Для современного .NET включите COM-хостинг (EnableComHosting): сборка даст файл *.comhost.dll, который регистрируется через regsvr32 из SysWOW64, потому что процесс VB6 32-битный. Подробности в документации Microsoft по COM-компонентам .NET.
- Для раннего связывания VB6 нужна библиотека типов. В современном .NET она не генерируется автоматически: подготовьте .idl, соберите .tlb и встройте его в comhost. Без библиотеки типов VB6 работает через CreateObject и позднее связывание.
- Подключите новый компонент в VB6 вместо старого кода, прогоните сравнительные тесты, выкатите.
- Повторяйте, пока в VB6 не останутся только формы. Затем заменяйте интерфейс: на WinForms, если важна скорость перехода, или на веб, если пользователей нужно вывести из десктопа.
Сборка .NET-компонента должна быть 32-битной (x86), иначе процесс VB6 её не загрузит. Если команде проще, на переходный период мост можно собирать и под .NET Framework 4.8 с регистрацией через regasm /tlb: путь старый, но с VB6 работает без сюрпризов.
Шаг 5. Тестирование и вывод из эксплуатации
У VB6-приложений почти никогда нет автотестов, поэтому главный инструмент проверки здесь сравнение. Перед стартом снимите эталоны: выходные файлы, отчёты, содержимое таблиц после типовых операций на копии рабочей базы. После каждого этапа те же сценарии прогоняются на новой версии, результаты сравниваются автоматически.
- Характеризационные тесты на перенесённую логику: фиксируют текущее поведение, даже если оно кажется странным. Как их писать, разобрано в статье о тестах для legacy VB.NET.
- Параллельная работа. Несколько недель старая и новая версии обрабатывают одни и те же данные, расхождения разбираются по одному.
- Отчёты и печатные формы сверяются отдельно: это самая заметная для пользователей часть. Замену Crystal Reports разбирали в отдельном материале.
- Развёртывание. Регистрация COM, права на каталоги, 32-битные драйверы. Сценарий установки пишется заранее и проверяется на чистой машине.
Вывод VB6 из эксплуатации стоит планировать как отдельный этап с датой: убрать регистрацию компонентов, удалить старые установщики, заархивировать сборочную машину вместе с исходниками на случай расследований.
Как это делают сегодня
Вопросы и ответы
Можно ли автоматически конвертировать 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, сторонние генераторы или отчёты кодом) и сверка печатных форм на эталонных данных.