Microsoft Photos: Migrating from UWP to Windows App SDK
The Microsoft Photos App team recently released a major update, switching platforms from UWP to Windows App SDK. This blog post documents our experience switching platforms, including some impactful benefits and some interesting technical challenges.
The new Photos application is already fully rolled out to Windows Insiders and is now rolling out to Retail customers starting with version 2024.11050.3002.0 and above.
Concurrent Development & Replatforming
As one of the most frequently used apps, we’re continually releasing new features such as Slideshow, Background Removal and Generative Erase. Maintaining the ability to ship new features like these on UWP, whilst also progressing the platform switch to Windows App SDK was paramount. In simple terms, this meant all changes – both new features and Windows App SDK changes – had to go into our primary development branch. To do this with the least amount of disruption, we adopted some strategies to ensure code changes were compatible with both platforms concurrently:
- Parallel Pull Request build validation for both UWP & Windows App SDK app variants
- Conditional compilation (ifdefs) for similar but incompatible APIs
- Namespace aliases for equivalent Windows:: and Microsoft:: APIs
#ifdef WIN_APP_SDK namespace WUXM = winrt::Microsoft::UI::Xaml::Media; #else namespace WUXM = winrt::Windows::UI::Xaml::Media; #endif
- Conditional inclusion of XAML source files since conditional compilation is unsupported
Processes & Integrity Level
In UWP applications, processes run at lowIL (low integrity level), also known as ‘AppContainer’, meaning certain APIs are restricted or could require additional user confirmation prompts. In Win32 applications, including Windows App SDK, processes generally run at mediumIL (medium integrity level), meaning the app has a higher privilege level.
Using Windows App SDK, we can now save an edited file in the same folder as the original file (e.g. “foo_edited.jpg”) without requesting the user to choose the destination folder.
Due to reasons including cross-platform compatibility and privilege checking, equivalent UWP APIs such as StorageFolder.GetFilesAsync can be orders of magnitude slower than their corresponding Win32 APIs such as FindNextFile. This is especially true for file system APIs, and when dealing with large photo collections spanning 100,000+ files, the performance difference could be significant – seconds vs minutes.
PhotosService.exe
Requiring users to wait several minutes to see all their media wouldn’t be a great user experience. To achieve acceptable performance with the UWP version of the Photos App, we used a multi-process architecture including both a lowIL primary process, and a mediumIL background process “PhotosService.exe” – a restricted capability only available to verified publishers.
Implementing this required significant complexity:
- Using WAP (Windows Application Packaging) to package both UWP and Win32 Applications for deployment
- Adding the restricted “runFullTrust” capability in the AppxManifest to allow the inclusion of a mediumIL executable in the package
- Building an IPC (interprocess communication) system using Named Pipes to allow RPC calls between two processes:
With the migration to Windows App SDK, this complex logic has been removed and integrated into a single process, dramatically simplifying our app architecture, and bringing improved performance due to the removal of interprocess communication.
One important point on the new approach is that Photos is still a multi-threaded application, and to receive File System notification events it was necessary to implement a headless window on a separate thread to isolate it from the XAML UI thread.
WebView2
Another huge benefit of Windows App SDK is the addition of WebView2, built upon the new Chromium-based Edge browser. The Photos App uses web tech in a few places, including with our cross-platform image editor used in both OneDrive and the Photos App. Some key benefits of WebView2 include:
- WebGL support enabling improved image rendering quality.
- Superior performance when sharing high quality images between the native and web layers using SharedBuffer.
- Supporting a more up to date version of Chromium, which carries the latest improvements and security updates.
- Allowing us to optimize the performance of our AI Service which requires sending pixel buffers back and forth from our Web Editor to our Native App for AI inference.
Maintenance and Support
As an Inbox app (included in Windows), we need to ensure Photos is running reliably for users across all supported versions of Windows. In Windows App SDK, most of the platform code is shipped as part of the WindowsAppRuntime package, in stark contrast to UWP where it’s all shipped as part of the Windows operating system.
The key difference between these two models is that users automatically get the latest platform updates to the Photos App on Windows App SDK, whereas in UWP they would have to wait for those changes to be included in Windows Update servicing patches.
In practical terms, this means we’ve often needed to use polyfills to patch bugs, re-implement missing APIs, or even disable features entirely on older OS versions. With Windows App SDK this is no longer needed, saving precious development time and reducing the testing overhead required for different OS versions.
Technical Challenges
ASTA vs STA
In UWP, the threading model was based on ASTA (Application Single-Threaded Apartment) which has a mechanism to protect the XAML UI thread against reentrancy. In contrast, Windows App SDK uses a regular STA model which requires some extra care when executing certain calls from the XAML UI thread, which could otherwise cause reentrancy and Stowed Exceptions.
For most of the cases the fix would be to re-enqueue the problematic call with the DispatcherQueue if it has to run in the UI thread. Another approach is to offload certain tasks to a background thread to decouple the re-entrant logic from the UI thread.
AutoPlay Support
One major feature of Photos is the ability for users to connect flash drives and mobile phone devices to import their media files. In Windows App SDK this feature has not yet been implemented, but there is a good alternative using Win32 shell APIs and desktop3:AutoPlayHandler.
This feature works by deploying and running a separated COM server process that handles autoplay activation and launches the Photos App’s import workflow.
Looking Ahead
Switching to Windows App SDK has allowed the Photos App to continue using the beautiful, cohesive, native user interface components included in WinUI, whilst adding the ability to directly call Win32 APIs and maintaining compatibility with the majority of UWP APIs. On the platform side, switching to Windows App SDK enables all Photos App users to receive the latest stability & performance improvements immediately, since the Windows App Runtime updates as a dependency of the Photos App package install.
Upgrading from UWP to Windows App SDK represents a larger change than previous Windows app platform updates, however the corresponding benefits significantly outweigh the development cost.
In the future we’ll be taking further advantage of Windows App SDK by having each Photos App window run in its own process – an architecture already used with overwhelming success in Chromium-based web browsers such as Microsoft Edge. Enjoy this sneak-peek of the upcoming performance improvements!
Resources
To learn more about getting started with WinUI & Windows App SDK visit https://aka.ms/windev and check out these videos:
Navigating Win32 App Development with WinUI and WPF | BRK241
How to create superior experiences with WinUI and WPF | BRK244