
WinForms-приложение на VB.NET под Linux и macOS: Wine, Avalonia, Uno Platform или .NET MAUI
Заказчик просит «чтобы работало и на маке», а в отделе появились ноутбуки с Linux. WinForms-приложение на VB.NET, которое честно служит десять лет, на этих машинах не запускается. Разбираем, какие есть варианты: от запуска без переписывания до переноса интерфейса на Avalonia, Uno Platform или .NET MAUI.
Выбор зависит от того, какие платформы действительно нужны. Если кроме Windows речь идёт только о macOS и Linux на рабочих местах, хватает desktop-фреймворка. Если параллельно бизнес хочет мобильный клиент для сотрудников в поле, разумнее сразу думать об одной кодовой базе для всех устройств. Такую задачу часто отдают на кроссплатформенную разработку приложений для iOS и Android, а desktop-часть переводят на тот же стек. Ниже разбираем варианты по порядку: что они умеют, чего стоят и где ломаются.
Почему WinForms не запускается на Linux и macOS?
Windows Forms это тонкая обёртка над Win32: каждое окно и каждый контрол создаются через user32.dll, рисование идёт через GDI и GDI+, а сообщения обрабатываются оконной процедурой Windows. Когда Microsoft перенесла WinForms в .NET Core 3.0 и далее, она перенесла именно эту обёртку, а не написала новый движок отрисовки. Поэтому шаблон net8.0-windows в проекте не случайность: библиотека физически не может работать без Windows.
К этому добавляется System.Drawing. Начиная с .NET 6 пакет System.Drawing.Common официально поддерживается только на Windows, на других ОС вызовы выбрасывают PlatformNotSupportedException (описание изменения на Microsoft Learn). Если ваш код рисует отчёты, графики или штрихкоды через Graphics и Bitmap, это придётся заменить даже в той части, которая к формам не относится.
Свойство EnableWindowsTargeting в проекте позволяет собрать WinForms-приложение на Linux-машине, например в CI. Запустить результат на Linux оно не позволяет, это частое недоразумение.
Какие варианты есть: сравнение
Сведём варианты в одну таблицу. Оценки трудоёмкости даны для типичного учётного приложения на 30–60 форм с бизнес-логикой в отдельных модулях.
| Вариант | Платформы | Что переписывать | Трудоёмкость | Когда подходит |
|---|---|---|---|---|
| Wine + .NET Framework | Linux, частично macOS | Ничего | Дни | Внутренние утилиты, временное решение |
| Mono WinForms | Linux, macOS | Ничего или мелочи | Дни–недели | Старые простые приложения на .NET Framework, без развития |
| Avalonia | Windows, macOS, Linux, плюс iOS, Android, браузер | Все формы | Месяцы | Desktop-first, нужен Linux |
| Uno Platform | Windows, macOS, Linux, iOS, Android, WebAssembly | Все формы | Месяцы | Нужен ещё и веб-клиент из того же кода |
| .NET MAUI | Windows, macOS, iOS, Android | Все формы | Месяцы | Linux не нужен, нужны телефоны |
| Веб-интерфейс (Blazor, SPA) | Любой браузер | Все формы плюс серверная часть | Месяцы | Много пользователей, удалённая работа |
| Удалённый рабочий стол (RDS, VDI) | Любая ОС с клиентом | Ничего | Дни | Мало пользователей, нужен результат сегодня |
Первые два и последний варианты не меняют приложение, они меняют способ его доставки. Остальные требуют переписать интерфейс, и выбор между ними определяется не вкусом команды, а списком платформ и тем, насколько интерфейс должен выглядеть «родным».
Можно ли обойтись без переписывания: Wine и Mono
Wine умеет запускать приложения .NET Framework: в нём есть собственная сборка Mono (wine-mono), которая подменяет .NET Framework, а при необходимости можно поставить и оригинальный .NET Framework 4.8 через winetricks. Простые формы с кнопками, таблицами и DataGridView обычно работают. Проблемы начинаются на сторонних контролах (DevExpress, Infragistics, старые ActiveX), печати, работе с COM и драйверами устройств. Каждое обновление Wine может как починить, так и сломать отдельную форму, поэтому для клиентского продукта этот путь не годится, а для внутренней утилиты бухгалтерии на пару человек вполне.
Mono WinForms исторически позволял запускать сборки .NET Framework на Linux и macOS напрямую. Но Microsoft передала проект Mono организации WineHQ, последний крупный релиз вышел в 2019 году, а сайт проекта прямо рекомендует переходить на современный .NET. Приложения на .NET 8 и новее Mono не запустит вовсе. Если ваша программа уже обновлена до .NET 8, этот вариант для неё закрыт.
Avalonia: когда главное desktop и Linux
Avalonia рисует интерфейс сама, через Skia, а не через нативные контролы ОС. Поэтому окно выглядит одинаково на Windows, macOS и Linux, а список платформ шире, чем у остальных: Windows, macOS, Linux, плюс iOS, Android и браузер через WebAssembly (официальный список платформ). Лицензия открытого ядра MIT, коммерческие дополнения у разработчиков фреймворка платные.
Для команды, пришедшей из WinForms, главное отличие не в синтаксисе, а в модели. Интерфейс описывается разметкой XAML, данные привязываются к свойствам ViewModel, а не записываются в TextBox1.Text из обработчика кнопки. Писать в стиле code-behind в Avalonia можно, но тогда теряется смысл переноса: следующую доработку снова придётся делать вручную в трёх местах.
- Плюсы: Linux поддерживается полноценно, интерфейс предсказуем на всех ОС, приложение компактнее и стартует быстрее, чем на MAUI.
- Минусы: внешний вид не «родной» для macOS, визуального дизайнера уровня WinForms нет, часть привычных компонентов (сложные гриды, отчёты) придётся подбирать заново.
- Осторожно: коммерческий продукт Avalonia XPF рассчитан на перенос WPF-приложений, а не WinForms. Формы WinForms он не запускает.
.NET MAUI и Uno Platform: когда нужны ещё и телефоны
.NET MAUI это преемник Xamarin.Forms от Microsoft. Он использует нативные контролы каждой платформы и поддерживает Windows, macOS (через Mac Catalyst), iOS и Android. Linux в списке нет, и Microsoft не обещает его добавить (поддерживаемые платформы .NET MAUI). Если рабочие места на Linux для вас обязательны, MAUI отпадает сразу, даже если остальное в нём нравится.
MAUI силён там, где главное мобильные устройства: склад, выездные сотрудники, торговые представители. Тогда desktop-версия на Windows и macOS получается почти бесплатно из того же проекта. Подробнее о переносе десктопных сценариев на телефон мы писали в статье о переносе VB6- и WinForms-приложения на мобильные устройства.
Uno Platform построен на API WinUI и XAML и покрывает самый широкий набор целей: Windows, macOS, Linux, iOS, Android и браузер через WebAssembly. Его выбирают, когда кроме desktop нужен веб-клиент из того же кода и не хочется держать отдельную команду фронтенда. Цена за это более сложная сборка и необходимость разбираться с особенностями каждой цели.
Что делать с кодом на VB.NET?
Здесь начинается специфика именно VB.NET. Avalonia, MAUI и Uno официально ориентированы на C#: шаблоны проектов, генераторы кода для XAML и примеры в документации на C#. Писать UI-слой на VB.NET технически возможно в отдельных случаях, но вы окажетесь один на один с проблемами, о которых никто не писал.
Практичная схема выглядит так: интерфейс пишется на C#, а вся бизнес-логика, расчёты и доступ к данным остаются в библиотеках классов на VB.NET, которые подключаются к UI-проекту как обычные ссылки. Компилятор VB.NET в современном .NET поддерживается, библиотеки с целевой платформой net8.0 (без суффикса -windows) работают на любой ОС.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- без -windows: библиотека должна собираться и работать на любой ОС -->
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Billing.Core</RootNamespace>
<OptionStrict>On</OptionStrict>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
</Project>Если такая библиотека не собирается без -windows, это лучший способ найти скрытые зависимости от Windows. Типичный список того, что придётся заменить:
My.Computer.RegistryиMicrosoft.Win32.Registry: настройки переносятся в JSON-файл в каталоге пользователя;System.Drawingдля генерации картинок и отчётов: замена на SkiaSharp или ImageSharp;- пути вида
"C:\Data\" & fileName: толькоPath.CombineиEnvironment.GetFolderPath, и помните, что файловая система Linux чувствительна к регистру; - COM-объекты и автоматизация Excel через
CreateObject: замена на библиотеки, работающие с файлом напрямую (OpenXML, ClosedXML); - P/Invoke в user32, kernel32 и сторонние нативные DLL: для каждой платформы нужен свой аналог или отказ от функции;
- Windows-аутентификация и доступ к SQL Server по Integrated Security: на Linux и macOS понадобится Kerberos или логин по паролю.
Перед выносом логики стоит закрепить её поведение тестами, иначе вы не узнаете, что расчёт изменился. Как это сделать в старом проекте, разбирали в статье про модульные тесты для legacy-кода на VB.NET.
Пошаговый план переноса
Порядок работ, который снижает риск и позволяет остановиться на любом шаге с работающим результатом:
- Обновите проект до современного .NET, если он ещё на .NET Framework. Без этого ни один из новых фреймворков не подключится. Процесс подробно описан в статье о переносе WinForms на VB.NET в .NET 8.
- Составьте инвентарь: список форм с частотой использования, сторонние компоненты, обращения к реестру, COM, печать, нативные DLL.
- Вынесите логику из форм в библиотеку
net8.0на VB.NET. Обработчики кнопок должны вызывать методы сервиса, а не содержать SQL и расчёты. - Покройте библиотеку тестами на эталонных данных: сравнение итогов, сумм, выгрузок.
- Выберите UI-фреймворк по списку платформ: Linux обязателен, значит Avalonia или Uno; нужны телефоны без Linux, значит MAUI; нужен браузер, значит Uno или веб.
- Сделайте пилот на 3–5 формах, включая самую сложную (обычно это грид с редактированием и печать). Пилот покажет реальную скорость переноса лучше любой оценки.
- Переносите формы пачками по сценариям пользователей, а не по алфавиту. Старое WinForms-приложение живёт параллельно на Windows, пока новое не закроет все сценарии.
- Настройте сборку и поставку под каждую ОС: подпись и нотаризация для macOS, пакеты deb, rpm или AppImage для Linux, MSIX или установщик для Windows.
Типичные ошибки
- Перенос «один к одному». Копирование каждой формы с теми же размерами в пикселях приводит к интерфейсу, который плохо выглядит на всех ОС. Используйте адаптивные контейнеры, а не абсолютные координаты.
- Выбор MAUI ради Linux. Случается чаще, чем кажется: фреймворк от Microsoft выглядит безопасным выбором, а потом выясняется, что Linux он не поддерживает.
- Попытка оставить UI на VB.NET любой ценой. Экономия на изучении C# оборачивается неделями борьбы с инструментами. Логика на VB.NET остаётся, а слой форм проще писать на том языке, на который рассчитан фреймворк.
- Забытая печать. В WinForms печать идёт через
PrintDocumentи драйверы Windows. На других ОС её приходится делать через генерацию PDF и системный диалог, и это стоит заложить в оценку отдельно. - Отсутствие пилота. Оценка «перенесём 50 форм за два месяца» без пилота почти всегда занижена в полтора-два раза.
Как это делают сегодня
Вопросы и ответы
Будет ли WinForms работать на Linux в будущих версиях .NET?
Нет. Microsoft переносила WinForms в .NET как обёртку над Win32 и не планирует делать её кроссплатформенной. Для Linux и macOS нужен другой UI-фреймворк или запуск через Wine.
Можно ли писать интерфейс Avalonia или MAUI на VB.NET?
Официальных шаблонов и генераторов кода для VB.NET у этих фреймворков нет, документация и примеры на C#. Практичный путь: интерфейс на C#, а бизнес-логика остаётся в библиотеках классов на VB.NET с целевой платформой net8.0.
Что выбрать, если нужен Linux и мобильные устройства?
Avalonia или Uno Platform: оба поддерживают Windows, macOS, Linux, iOS и Android. .NET MAUI в этом случае не подходит, потому что Linux он не поддерживает.
Сколько времени занимает перенос WinForms-приложения на Avalonia?
Для учётного приложения на 30–60 форм обычно несколько месяцев, если логика уже отделена от форм. Точную скорость покажет пилот на 3–5 формах, включая самую сложную.
Подойдёт ли Wine для клиентского продукта?
Обычно нет. Простые формы под Wine работают, но сторонние контролы, печать и COM ломаются непредсказуемо, а каждое обновление Wine меняет поведение. Для внутренних утилит и на время переноса это допустимый вариант.