microsoft / microsoft/WindowsAppSDK

Single instance app redirect causes COM Exception when reading Kind property of AppActivationArguments

Open
#6,573 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area-Activation needs-triage
Dominant language
C++
Stars
4.7k
Forks
471
Avg merge
3d 13h
Merged PRs (30d)
28

Description

Describe the bug

Occasionally my app (on the MS Store) reports COM Exceptions when the background process that is part of the MSIX package launches the 'main' app at the moment the main app is executing. I use the WinAppSDK redirect api to invoke and handle the redirect.
The exception listed below shows that access to the Kind property of AppActivationArguments causes an error.

System.Runtime.InteropServices.COMException (0x800706BA)
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|38_0(Int32 hr)
   at WinRT.ExceptionHelpers.ThrowExceptionForHR(Int32 hr)
   at ABI.Microsoft.Windows.AppLifecycle.IAppActivationArgumentsMethods.get_Kind(IObjectReference _obj)
   at Microsoft.Windows.AppLifecycle.AppActivationArguments.get_Kind()
   at SyncFolder.App.HandleActivationAsync(AppActivationArguments activationArgs): line 267
   at SyncFolder.App.<>c__DisplayClass50_0.<<OnAppRedirectActivated>b__0>d.MoveNext(): line 239

The redirecting app redirects as follows:

    [STAThread]
    static void Main(string[] args)
    {
        WinRT.ComWrappersSupport.InitializeComWrappers();

        // Check BEFORE Application.Start() so the XAML runtime never starts
        // for a redirect-instance, preventing Fail Fast crashes and Partner Center "Unknown" failures.
        var instance = AppInstance.FindOrRegisterForKey(App.cInstanceKey);
        if (!instance.IsCurrent)
        {
            var activationArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
            instance.RedirectActivationToAsync(activationArgs).AsTask().Wait();

            // Short pause: Give the main instance the chance to read all properties
            // from activationArgs via RPC before this process (and thereby
            // the RPC server behind it) disappears. Prevents RPC_S_SERVER_UNAVAILABLE
            // (0x800706BA) in the main instance when calling get_Kind().
            Thread.Sleep(200);

            return; // Clean return - no XAML teardown, no COM issues
        }

        instance.Activated += (sender, args) => App.sAppInstance?.OnAppRedirectActivated(sender, args);

        Application.Start((p) =>
        {
            var context = new DispatcherQueueSynchronizationContext(
                DispatcherQueue.GetForCurrentThread());
            SynchronizationContext.SetSynchronizationContext(context);
            new App();
        });
    }

When reading about possible causes there seems to be some general understanding that when the current instance doesn't immediately processes the redirect (e.g. due to system load) and the redirecting instance has allready closed, that the AppActivationArguments cannot be retrieved anymore.
Therefore I have put a small delay before closing but don't think this really helps.

Currently the main app reacts on the Activated event as follows:

        public void OnAppRedirectActivated(object sender, AppActivationArguments args)
        {
            sRedirectInProgress = true;
            Logger.LogInformation($"{_appProcessID} - OnAppRedirectActivated: {args.Kind}");

            _dispatcherQueue?.TryEnqueue(async () =>
            {
                try
                {
                    await HandleActivationAsync(args);
                }
                catch (Exception ex)
                {
                    Logger.LogInformation($"{_appProcessID} - Exception in OnAppRedirectActivated: 0x{ex.HResult:X8}, message: {ex.Message}");
                    ErrorTracking.SendException(ex, "Redirect");
                }
                finally
                {
                    sRedirectInProgress = false;
                }
            });

            if (_dispatcherQueue == null)
            {
                sRedirectInProgress = false;
                Logger.LogInformation($"{_appProcessID} - DispatcherQueue is null, redirect not handled.");
            }
        }

I know that dispatching the handling to the dispatcher queue delays access to AppActivationArguments even more.

I really need to know how to deal with this. Do I have to pre-read the args immediately in the Activated event handler? And not only Kind but also Data? Will that help? Will there anyhow be the possibility that it fails?
Is there something missing in the Redirect API?

Steps to reproduce the bug

I don't manage to reproduce this myself. It occurs sometimes on systems of people using my app.

Expected behavior

No response

Screenshots

No response

NuGet package version

1.8.260416003

Packaging type

Packaged (MSIX)

Windows version

Windows 11 version 24H2 (26100, June 2025 Update)

IDE

No response

Additional context

No response

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the WinAppSDK single-instance redirect API and the AppActivationArguments path shown in the report, especially the Activated handler and the call to Kind. Investigate whether redirect arguments remain readable after the redirecting process exits, and whether reading them immediately changes the outcome. The issue is resolved when the failure mode and a supported handling pattern, or a concrete API defect, are established; reproduction is currently unavailable.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.