Overall steps... Requires WinAppSDK 1.0.0 Preview 3 or greater and you must COMPILE FOR x64 (there's a known bug where this doesn't work from x86 apps)
- Add code to find existing instance, and if found, redirect and kill current process using
System.Diagnostics.Process.GetCurrentProcess().Kill()
(the WinUI 3Exit()
method doesn't work) - Add code to handle the activation redirection
- Install the Microsoft.Windows.CsWin32 NuGet package
- Add the NativeMethods.txt file with two methods,
ShowWindow
andSetForegroundWindow
(the WinUI 3Activate
and AppWindowShow
methods don't work) - In the redirection event, call
ShowWindow
andSetForegroundWindow
Full code sample: https://github.com/andrewleader/RedirectActivationWinUI3Sample
Include prerelease when searching, since it's a prerelease package
The file contents should simply be...
SetForegroundWindow
ShowWindow
protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
// Get the activation args
var appArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
// Get or register the main instance
var mainInstance = Microsoft.Windows.AppLifecycle.AppInstance.FindOrRegisterForKey("main");
// If the main instance isn't this current instance
if (!mainInstance.IsCurrent)
{
// Redirect activation to that instance
await mainInstance.RedirectActivationToAsync(appArgs);
// And exit our instance and stop
System.Diagnostics.Process.GetCurrentProcess().Kill();
return;
}
// Otherwise, register for activation redirection
Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().Activated += App_Activated;
m_window = new MainWindow();
m_window.Activate();
}
private void App_Activated(object sender, Microsoft.Windows.AppLifecycle.AppActivationArguments e)
{
// Bring the window to the foreground... first get the window handle...
var hwnd = (Windows.Win32.Foundation.HWND)WinRT.Interop.WindowNative.GetWindowHandle(m_window);
// Restore window if minimized... requires Microsoft.Windows.CsWin32 NuGet package and a NativeMethods.txt file with ShowWindow method
Windows.Win32.PInvoke.ShowWindow(hwnd, Windows.Win32.UI.WindowsAndMessaging.SHOW_WINDOW_CMD.SW_RESTORE);
// And call SetForegroundWindow... requires Microsoft.Windows.CsWin32 NuGet package and a NativeMethods.txt file with SetForegroundWindow method
Windows.Win32.PInvoke.SetForegroundWindow(hwnd);
}
Only x64 works right now, x86 won't properly detect the existing instance.
Also, instead of all that pinvoke stuff i just do
m_window.DispatcherQueue.TryEnqueue(() => { m_window?.Activate(); });
and works, it this not allowed ?