johnnys.newsjohnnys.news

by Joachim Leonfellner ✌️ i'm an indie dev in ❤️ with side-projects

Apr 21, 20232216 words in 15 min


Welcome to Hell - Windows Publishing with .NET MAUI

Update March 2024

Publishing a WinUI 3 app as a single exe is now possible. Check out my new post about this topic https://johnnys.news/2024/03/Revisited-WinUI-publishing-a-single-exe.

TL;DR

if you have an idea on how to publish a .NET MAUI app as a single file for Windows, please let me know. I tried everything i could find on the internet in the docs and on GitHub but nothing worked.

.NET MAUI publishing

this is my biggest pain point with .NET MAUI at the moment. I have a very simple requirement for one of my applications. My goal was to publish and distribute a single file for both macOS and Windows. On macOS this is easy a build of the application generates a .app file. Actually, this is not really a single file as you can show and navigate the package contents but for distribution this works very well (once code signing is done) - just click and run, beautiful ☀️

Usually, developers tend to complain about apple platforms when it comes to publishing and distribution but the hours and effort i invested in getting a Windows app published are just insane. On the apple side it’s mostly code signing and notarization which can be tricky - if you are interested about this feel free to check the code of my action for Dots on GitHub. But in this post i want to focus on Windows publishing and some of my findings from the last couple of days were i tried to get a .NET MAUI application published.

Right click -> Publish

The obvious first thing for a developer who spends most of his time inside Visual Studio is the classic right click -> Publish. I quickly found out this this simply crashes the IDE immediately 💥 great start…

Since i have used single file executables in the past in dotnet apps the next thing i tried was setting the <PublishSingleFile> flag to true. The <PublishSingleFile>true</PublishSingleFile> flag works fine for dotnet projects like console apps but just fails for .NET MAUI (more specifically Windows App SDK) projects. Calling dotnet publish -f net7.0-windows10.0.19041.0 -c Release shows the following error

1
2
3
4
5
6
7
C:\Program Files\dotnet\sdk\7.0.200-preview.22628.1\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.CrossGen.targets(465,5):
error MSB6006: "C:\Users\dev\.nuget\packages\microsoft.netcore.app.crossgen2.win-x64\7.0.0\tools\crossgen2.exe" exited
with code -1073741819. [D:\dev\Dots\src\Dots.csproj::TargetFramework=net7.0-windows10.0.19041.0]
C:\Program Files\dotnet\sdk\7.0.200-preview.22628.1\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.CrossGen.targets(353,5):
error NETSDK1096: Optimizing assemblies for performance failed. You can either exclude the failing assemblies from being
optimized, or set the PublishReadyToRun property to false. [D:\dev\Dots\src\Dots.csproj::TargetFramework=net7.0-windows1
0.0.19041.0]

Next step was to set PublishReadyToRun to false - as indicated by the error message. A pity since i want to use ReadyToRun for a better app performance. I still tried it to see if i can get a single executable.

another attempt

This time the build succeeded, and a bigger executable was created in the publish folder. I thought i was done - but no…
The application simply fails to launch. The Windows event viewer shows the following error.

Windows Event Viewer

Turns out that i’m not the only one with this issue - there are dozens of reports and similar issues on StackOverflow and GitHub spread across multiple repositories:

https://github.com/microsoft/WindowsAppSDK/issues/3042
https://github.com/microsoft/microsoft-ui-xaml/issues/7143
https://github.com/dotnet/maui/issues/4329

WinUI3 + Windows App SDK

To investigate further i stopped experimenting with a .NET MAUI project and created a blank WinUI 3 + Windows App SDK project, since this is what MAUI for Windows is based on. I followed the steps from the documentation and set up the project to be unpackaged. I tried to use a configuration which bundles the runtime and the Windows App SDK with the application to have a single exe to distribute.

1
2
3
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<WindowsAppSDKSelfContained >true</PublishSingleFile>

Since i don’t want to publish a MSIX installer - i removed the Package.appxmanifest from the project and changed my launchSettings.json to only include the unpackaged configuration:

1
2
3
4
5
6
7
{
"profiles": {
"WASDK_Blank (Unpackaged)": {
"commandName": "Project"
}
}
}

I used the following command to publish the application:

1
dotnet publish -f net7.0-windows10.0.19041.0 -c Release -p:Platform=x64

and got the output that a task is missing:

1
2
3
4
5
6
7
8
9
10
C:\Users\dev\.nuget\packages\microsoft.windowsappsdk\1.2.221209.1\buildTransitive\MrtCore
.PriGen.targets(911,5): error MSB4062: The "Microsoft.Build.Packaging.Pri.Tasks.ExpandPriCo
ntent" task could not be loaded from the assembly C:\Program Files\dotnet\sdk\7.0.300-previ
ew.23179.2\\Microsoft\VisualStudio\v17.0\AppxPackage\\Microsoft.Build.Packaging.Pri.Tasks.d
ll. Could not load file or assembly 'C:\Program Files\dotnet\sdk\7.0.300-preview.23179.2\Mi
crosoft\VisualStudio\v17.0\AppxPackage\Microsoft.Build.Packaging.Pri.Tasks.dll'. The system
cannot find the path specified. Confirm that the <UsingTask> declaration is correct, that
the assembly and all its dependencies are available, and that the task contains a public cl
ass that implements Microsoft.Build.Framework.ITask. [C:\Users\dev\WinPublish\Win
Publish.csproj]

If someone has a solution to this i would be very happy to hear about it - so far i was not able to get even a blank WinUI 3 application published as a single file. I experimented with AOT and ReadyToRun builds (with and without trimming) which all work fine, but as soon I set to true the application fails to launch. I ended up with a very frustrating trial-and-error approach to test all possible combinations of the following flags in the csproj file:

1
2
3
4
5
6
7
8
9
10
11
12
<PublishSingleFile>
<SelfContained>
<WindowsAppSdkSelfContained>
<WindowsPackageType>
<WindowsAppSdkBootstrapInitialize>
<IncludeNativeLibrariesForSelfExtract>
<BuiltInComInteropSupport>
<IncludeNativeLibrariesInSingleFile>
<IncludeNativeLibrariesForSelfExtract>
<PublishAot>
<PublishReadyToRun>
<PublishTrimmed>

but had no luck - neither from the command line via dotnet publish nor from Visual Studio -> Publish. Some of these flags are not even documented i just found them randomly on GitHub, StackOverflow or in the targets source code.

Unpackaged Application

at this point i gave up on my single file goal and tried to publish the application with all default settings and the standard dotnet publish command. All i did was changing WindowsPackageType from MSIX to <WindowsPackageType>None</WindowsPackageType>. This setup should produce an unpackaged application (terrible naming btw). I’m now calling dotnet publish -f net7.0-windows10.0.19041.0 -c Release which produces a publish folder in bin/Release/net7.0-windows10.0.19041.0 which contains an executable and a whole bunch of required dlls and localization directories.

Dots
With over 416 files i clearly missed my goal of publishing a single executable. But at the current level of frustration i thought so far so good - i can just zip this folder and distribute it. But no - the application launches but assets like images and fonts are not loaded. At this point a build of Dots would look like this:

Dots

Back to GitHub and StackOverflow to find a solution. Turns out that there are some open issues in MAUI and Windows App SDK, but they don’t have any traction or recent updates:

https://github.com/dotnet/maui/issues/10526
https://github.com/microsoft/Win2D/issues/891
https://github.com/microsoft/microsoft-ui-xaml/issues/7866
https://github.com/dotnet/maui/issues/10899
https://github.com/dotnet/maui/issues/9104

I’m also using a custom font to my blank WinUI 3 project, and it also fails to render the glyphs. So, this one is most probably a general issue with the Windows App SDK and not specific to .NET MAUI. The underlying issue seems to be:
https://github.com/microsoft/Win2D/issues/891
which is now tracked as an internal non-public workitem.

I could find possible a workaround for the missing images, but on my side this again creates an exe that crashes on launch with the same error shown in the event viewer as above.

<RANT>

At this point i’m in a love hate relationship with .NET MAUI. I really like the idea of a single .NET framework for all platforms and the abstractions that MAUI provides to simplify some boilerplate tasks for cross platform development. On the other hand, i think that the current state of MAUI is still not great for developers. Critical issues are not fixed for months, and basic functionality is broken. Critical bugfixes get backported, but still developers have to wait for a Visual Studio update to get the fix (or rollback workloads manually which is a terrible experience). From my outside perspective it seems that the MAUI engineering team is understaffed, and engineers are too busy with fixing bugs and don’t even have the possibility to work on real innovations in the cross-platform space. If you compare it with the progress that Flutter or similar projects in the .NET ecosystem have made recently it feels like a joke. I feel really sorry for the developers that are working on MAUI, i see it daily in the GitHub repository that they are continuously working hard. But for me as a developer who is following the project across social media and podcasts it’s just frustrating to hear from PMs that everything MAUI is just “latest and greatest and perfectly shiny” - i don’t have such feelings when i try to publish my app, right now. As said i’m an active follower of the dotnet/maui repository i am of course aware of the issues that track the problems that i’m facing right now, but similar to a majority of the open issues those are not getting any attention and are just added to the backlog.

https://github.com/dotnet/maui/issues/3166
https://github.com/dotnet/maui/issues/10564

I mean it’s just infuriating when a framework is declared “production-ready”, but it can’t even produce a working app on Windows - where the SDK is maintained by a group in the same division of the company. It feels like the Windows App SDK is far from being a stable solid foundation for MAUI on Windows.

Maybe i am just too stupid to get this working or if publishing an app as a single executable is just a requirement that’s too exotic in 2023. I have been working with .NET since 2008 and i have never had such a frustrating experience with publishing an application. Documentation (which is usually very good for .NET) is either non-existent, outdated or simply too hard to find - i have the feeling that very specific knowledge is spread across the internet buried in GitHub issues or StackOverflow threads. I ended up with a lot of trial-and-error attempts and this blog post where i try to describe some of my findings from this chaotic journey. I usually want to share solutions and fixes to problems that i encounter during my work - not with this post unfortunately. Maybe some reader has a better understanding of the topic and can help out with a solution.

</RANT>

Issue Collection

adding some of the issues referenced here in this post - mostly for myself to keep track of them:

i’m already working on my next post about .NET MAUI which will be more positive - just had to get this topic off my chest.