Edit

Multi-instance apps with Windows App SDK

By default, a Windows App SDK desktop app can run multiple instances simultaneously. Each instance runs as a separate process. You can control this behavior using the Microsoft.Windows.AppLifecycle.AppInstance class to register instances, detect existing ones, and redirect activations.

Scenarios for multi-instance management

  • Single-instance enforcement — Redirect new activations to the already-running instance.
  • Key-based routing — Route different files or URIs to specific instances (for example, one instance per document).
  • Instance discovery — Enumerate all running instances to coordinate work.

Register an instance with a key

Use AppInstance.FindOrRegisterForKey in your app's Main method to claim a key. If the key is already registered by another instance, you can redirect the activation. The following custom Main method goes in Program.cs, before any XAML initialization:

using Microsoft.Windows.AppLifecycle;

public static class Program
{

[STAThread]
static async Task Main(string[] args)
{
    // Required before calling any other Windows App SDK or WinRT API
    // from a custom entry point.
    WinRT.ComWrappersSupport.InitializeComWrappers();

    // Determine a key for this activation
    string instanceKey = "main-instance";

    var activatedArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
    if (activatedArgs.Kind == ExtendedActivationKind.File)
    {
        var fileArgs = activatedArgs.Data as
            Windows.ApplicationModel.Activation.IFileActivatedEventArgs;
        // Use the file path as the instance key to route
        // each file to its own instance
        if (fileArgs?.Files is { Count: > 0 })
        {
            instanceKey = fileArgs.Files[0].Path;
        }
    }

    var instance = AppInstance.FindOrRegisterForKey(instanceKey);

    if (!instance.IsCurrent)
    {
        // Another instance owns this key — redirect activation to it
        await instance.RedirectActivationToAsync(activatedArgs);
        return; // Exit this process
    }

    // This instance owns the key — proceed with normal startup
    // Register for future redirected activations
    instance.Activated += OnActivated;

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

private static void OnActivated(object? sender, AppActivationArguments args)
{
    // Handle the redirected activation on the UI thread
    // For example, open the file or navigate to the URI
}

// App is the application type generated by the WinUI 3 project template
// (App.xaml / App.xaml.cs).
private partial class App : Microsoft.UI.Xaml.Application
{
}

}

Note

To use a custom Main method, disable the auto-generated entry point. In your .csproj, set <DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants> to append the symbol without overwriting existing definitions.

Enforce single-instance behavior

To make your app single-instance, always use the same key:

var instance = AppInstance.FindOrRegisterForKey("single-instance");

if (!instance.IsCurrent)
{
    await instance.RedirectActivationToAsync(
        AppInstance.GetCurrent().GetActivatedEventArgs());
    return;
}

Enumerate running instances

Use AppInstance.GetInstances() to discover all registered instances:

var instances = AppInstance.GetInstances();
foreach (var inst in instances)
{
    System.Diagnostics.Debug.WriteLine(
        $"Key: {inst.Key}, ProcessId: {inst.ProcessId}");
}

Unregister an instance

When your instance shuts down, the registration is removed automatically. You can also unregister explicitly:

AppInstance.GetCurrent().UnregisterKey();

Differences from UWP multi-instance

Feature UWP Windows App SDK
Namespace Windows.ApplicationModel.AppInstance Microsoft.Windows.AppLifecycle.AppInstance
Manifest requirement SupportsMultipleInstances attribute Not required for desktop apps
Instance discovery AppInstance.GetInstances() AppInstance.GetInstances() (same pattern)
Activation redirection AppInstance.RedirectActivationTo() AppInstance.RedirectActivationToAsync() (async)
Custom main entry point Required Required (same approach)