Человека далёкого от клиентской разработки на Windows все эти термины определённо путают. И даже среди MS-сообщества регулярно возникают споры жив UWP или мёртв. Причем главный вопрос в этом споре - а что же такое UWP?

Вот уже года 3 Microsoft проводит "рефакторинг" в своём "королевстве".  Несколько устав видеть одни и те же споры в твиттере, и оставлять одни и те же комментарии на хабре, я решил расписать как же многочисленные UI-фреймворки MS соотносятся между собой. Кто из них больше мёртв. Возможно, кому-то это поможет в выборе технологии для будущего проекта.

Windows API и Windows Runtime

Прежде чем начать разбираться с UI-фреймворками стоит сначала опуститься на уровень ниже, впрочем, без особых подробностей. В современной винде 2 основных API для работы приложений. Windows API (обычно сокращается до Win32) и Windows Runtime (WinRT). При разработке первый был ориентирован на язык С, и активно развивался вплоть до выхода Windows 8. Я не имею в виду, что этот API объявлен устаревшим, но все новые функции системы уже разрабатывются для WinRT. Хотя некоторые так же бекпортируются и в Win32. Приложения, которые работают через Win32 и используют его модель приложений и сервисов Microsoft называет классическими.

WinRT - вещь немного более сложная. Это даже не API, а способ взаимодействия с ним. Из вики:

WinRT has a rich object-oriented class-based type system that is built on the metadata. It supports constructs with corresponding constructs in the .NET framework: classesmethodspropertiesdelegates, and events.

Ключевое: есть объектно-ориентированные метаданные, которые описывают публичный интерфейс библиотеки: поддерживаются базовые классы (числа, строки), асинхронность (async/await), события. Начиная с Windows 8 весь новый API — это COM, с которым можно взаимодействовать через данный протокол. Любой язык, который реализует языковую проекцию в WinRT (C++/WinRTRust/WinRTPython/WinRT, С#/WinRT) может взаимодействовать с этим API, будто это нативная для языка библиотека. Компоненты WinRT могут быть написаны на любом их этих языков. Сам виндовый API написан при этом на C++.

Помимо объектно-ориентированности, новый API имеет версионирование, больший контроль доступа к вызовам. Некоторые системные вызовы могут делать только приложения определённых разработчиков, некоторые доступны по специальному ключу. Некоторые сокрыты весьма условно: если приложение попало на комп, оно может ими пользоваться. Но вот в Microsoft Store могут и не пустить.

Application Models

Два вышеописанных системных API в данный момент подразумевают две разных модели жизненного цикла приложений. Классическая модель — приложению можно почти всё, оно может залезть почти куда угодно, читать что угодно, прятать окна и свою деятельность. С одной стороны — это позволяет делать различные удобные штуки вроде Punto Switcher, или сворачивание в трей по закрытию окна (вопреки ожиданиям, это не стандартное поведение в Windows). С другой стороны, это развязывает руки любым троянам.

И это было одной из причин, почему для приложений, работающих с WinRT, за основу была взята модель из мобильных платформ — изолированные приложения с контролируемым системой жизненным циклом. Другой из озвученных причин является большая энергоэффективность мобильного подхода. Всё же значительное количество ПК — ноутбуки. Вылилось это в повсеместные ограничения, привязку времени жизни приложения и времени жизни его основного окна (пока-пока сворачивание в трей). А также сильные ограничения работы в фоновом режиме. На размен давались различные фоновые задачи, контролируемые системой, и легальные способы интеграции в систему (системные контракты, такие как Share UI). В Microsoft посчитали, что за неполные 9 лет за счет таких интеграций появилось около 40 возможных точек входа в приложение. В какой-то момент даже появилась возможность делать консольные приложения, работающие поверх WinRT.

Стоит так же отметить, что эти две модели не изолируют Win32 и WinRT API друг от друга. В UWP приложения всё так же можно подключать Win32-библотеки, пока это не открывает путь за пределы песочницы. Из Win32 можно дергать WinRT API, но для большей его части надо получить AppIdentity, до недавнего времени это означало, что приложение придётся запаковать и она станет чуть более изолированным. 

И, пожалуй, именно тут надо вспомнить про UWP (Universal Windows Platform). Технически это название для реализации Windows Runtime в Windows 10+. Дело в том, что Windows Runtime в телефонах и Windows Runtime в Windows 8 отличались настолько, что для них нужно было делать отдельные сборки приложений (даже для одной архитектуры процессора). С появлением Windows 10, ОС и рантайм допилили до того состояния, когда 1 сборка приложения может запускаться и на телефоне (тогда они ещё были), и на ПК. Так же к этому списку добавились XBox, IoT, Hololens и Teams (большая интерактивная "маркерная доска")

На практике, под сокращением UWP часто понимают именно UWP-приложения.

UI-фреймворки

Наконец можно поговорить про UI-фреймворки. С Windows Forms и WPF многие знакомы. UI, работающий поверх Win32 API. Отличаются способом верстки UI (дизайнер или XAML) и способом отрисовки (GDI или DirectX). С появлением WinRT, эти фреймворки особо не развиваются, но из-за огромного количества легаси приложений, Microsoft вынуждена поддерживать их. Например, в последних выпусках десятки значительно улучшена поддержка HDPI для WinForms.

Как такового маркетингового названия для UI-фреймворка в UWP нет. В зависимости от контекста используют понятия UWP-приложения и UWP XAML. Итак, UWP-приложения используют WinRT-модель приложений, XAML в качестве языка разметки и не требуют .NET. Фактически даже приложения, написанные на C#, собираются в нативный код, а не IL. XAML так же отличается от того, что используется в WPF, так как является развитием телефонного Silverlight (подмножества WPF). В итоге, с точки зрения верстки у XAML в UWP есть как отсутствующие фишки (например, multibindings), так и новые полезные фичи (например, компилируемые x:Bind), по сравнению с WPF. Кроме того, в UWP появился Composition API для визуально богатых, но экономичных с точки зрения ресурсов анимаций. И сделано много наработок для того, чтобы поддержать все богатство способов взаимодействия в современной Windows. Например, пункты контекстного меню становятся больше, если вызывать меню через тач.

WinUI

WinUI достоин отдельного упоминания, так как он един в двух лицах.

WinUI 2.x — UI-библиотека для UWP-приложений, содержащая в себе новые, в том числе экспериментальные, контролы. А также, обеспечивающая совместимость со старыми версиями Windows 10 (аналог AndroidX)

WinUI 3.x — часть Windows App SDK. Фактически это и есть UI-фреймворк для UWP, только оторванный от жизненного цикла UWP-приложений.

Обе версии сейчас развиваются параллельно.

Project Reunion он же Windows App SDK

Собственно, посмотрев на это обилие фреймворков (ещё и ввязавшись зачем-то в ReactNative), и выслушав жалобы разработчиков, в мае 2020 Microsoft анонсировала объединение подходов. Разработчики Windows Forms и WPF хотят писать стильные/модные/молодёжные приложения, получить доступ к новому API (в том числе различным системным триггерам, которые бывают довольно удобны). UWP-разработчики хотят получить больший доступ к системе и более простые способы распространения приложения, так как сейчас мимо стора распространять приложение не просто.

Собственно, WinUI 3.x является частью решения. Берём графический фреймворк от UWP-приложений, насаживаем его на жизненный цикл классических приложений. И все счастливы.

На самом деле, все конечно сложнее. И что за монстр Франкенштейна в итоге получится мы узнаем уже в конце года. Впрочем начать знакомиться можно уже сегодня.

Так жив ли больной?

UWP, как подсистема винды, никуда не денется в ближайшее время. Это всё ещё основной вектор развития API системы. Для UWP-приложений, которые нацелены только на десктоп, уже настало время планировать портирование на Windows App SDK. Недавно выпущенная версия 0.8 уже допускается в Microsoft Store. Если же приложение должно работать и на других платформах (Xbox, Hololens и т. д.), то тут придется ждать следующего года. Но рано или поздно, таки придется переехать на Windows App SDK.

Касательно классических приложений, покуда вам не нужны новые фичи платформы (пуши, возможность поделиться в ваше приложение, новый богатый UI и т. п.), то делать в общем-то тоже ничего не надо.

Если писать новое приложение, то стоит оценить Windows App SDK в текущем его состоянии. И возможно писать на нём.

А как же MAUI?

Всё что я писал до этого, касалось только Windows и никаких других ОС. Но у Microsoft есть Xamarin — .NET для мобилок (на самом деле mono для мобилок). Наработки xamarin вмерживаются в .NET 5 и 6. Собственно MAUI — .NET Multi-platform App UI — ничто иное как Xamarin.Forms, реализованные в .NET.

MAUI — абстракция над нативными UI-фреймворками.

Собственно, на винде это будет абстракцией над WinUI. У Xamarin.Forms есть поддерживаемая сообществом реализация поверх WPF.

Аналогичным образом ReactNative for Windows так же является абстракцией поверх WinUI. На нем, кстати, написан магазин на Xbox.

 Подытожим

  • UWP — название подмножества API Windows, но часто используется как сокращение для изолированных приложений, работающих на этом API.

  • WinUI — современный графический фреймворк для Windows

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

  •  MAUI — привязанная к .NET кроссплатформенная абстракция над нативным UI