Recently, I created a new WinUI 3 (v1.2) desktop app using Template Studio for WinUI. Because starting unpackaged apps in Debug
is so much faster than packaged apps, I chose an unpackaged app in the setup wizard. The resulting barebones code created an app that always crashed when closed using the Close
method or the Close
button on the System Menu
.
The app throws an unhandled exception which VS 2022
catches in App.g.i.cs in the following section:
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
You can disable this by setting the DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
variable in the project Properties
(under Build -> Conditional compilation symbols) but the program will still throw the error (this code simply gives you a convenient way to trap unexpected errors).
Can anyone explain why this is happening with an unmodified new project and how to correct it, please?
The template code generates a MainWindow
that is of the class WindowEx
. This nifty extension of the Window
class adds quite a few helpful features (see: WinUIEx Wiki) but some of them aren't completely documented yet. The WindowEx
class creates a WinUIEx.WindowManager
to manage the WindowEx
window. When the WindowEx
is closed, WinUIEx.WindowManager.Window_Closed()
is called which then calls WinUIEx.WindowManager.SavePersistence()
which is the cause of the crash mentioned above.
SavePersistence()
tries to save some of the window characteristics so they can be restored when the app restarts. However, the persistence services are only enabled for packaged apps, not unpackaged (which I used). To turn this behavior off, set the PersistenceId
property of the WinUIEx.WindowManager
instance to either null
, string.Empty
, or ""
(the template sets PersistenceId = "MainWindow"
by default). Just add
var manager = WinUIEx.WindowManager.Get(MainWindow);
manager.PersistenceId = string.Empty;
somewhere after MainWindow
has been instantiated (I put it in App.OnLaunched
). I hope this helps.