SoldatXwing
SoldatXwing

Reputation: 35

.NET MAUI (WinUI 3) custom URI protocol always opens a new instance instead of reusing the running app

I have a .NET MAUI app that needs to handle a custom URI scheme (dayplanner://) for authentication callbacks. On Android, the redirect triggers OnAppLinkRequestReceived(Uri uri) as expected, allowing me to capture the token parameters (?token=xyz&refreshToken=abc). However, on Windows (WinUI 3), whenever I open a link like dayplanner://?token=xyz&refreshToken=abc, a new instance of my app starts instead of reusing the already running instance.

Additionally, OnAppLinkRequestReceived is never called on Windows. I tried adding the following to my Package.appxmanifest:

<Extensions>
  <uap:Extension Category="windows.protocol">
    <uap:Protocol Name="dayplanner" />
  </uap:Extension>
</Extensions>

I also tried overriding OnLaunched(LaunchActivatedEventArgs args) or OnActivated(IActivatedEventArgs args) in my Windows-specific App.xaml.cs, but either these overrides don’t exist in MauiWinUIApplication or they don’t receive a ProtocolActivatedEventArgs when the link is opened.

I came across suggestions to use the Windows App SDK’s AppInstance API (for single-instancing and protocol handling), but so far, every time I test the URI link, it still opens a brand-new instance instead of passing the activation event to the existing one.

Upvotes: 0

Views: 58

Answers (1)

SoldatXwing
SoldatXwing

Reputation: 35

Solution was:

// In your App.xaml.cs

public partial class App : MauiWinUIApplication
{
    // ...

    protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        var appInstance = AppInstance.GetCurrent();
        var e = appInstance.GetActivatedEventArgs();

        // If it's not a Protocol activation, just launch the app normally
        if (e.Kind != ExtendedActivationKind.Protocol ||
            e.Data is not ProtocolActivatedEventArgs protocol)
        {
            appInstance.Activated += AppInstance_Activated;

            base.OnLaunched(args);
            return;
        }

        // If it's a Protocol activation, redirect it to other instances
        var instances = AppInstance.GetInstances();
        await Task.WhenAll(instances
            .Select(async q => await q.RedirectActivationToAsync(e)));

        return;
    }

    private void AppInstance_Activated(object? sender, AppActivationArguments e)
    {
        if (e.Kind != ExtendedActivationKind.Protocol ||
            e.Data is not ProtocolActivatedEventArgs protocol)        
        {
            return;
        }

        // Process your activation here
        Debug.WriteLine("URI activated: " + protocol.Uri);
    }

}

Also answered here: https://stackoverflow.com/a/79123126/17302880

Upvotes: 0

Related Questions