Aplicações multi-instância com SDK de Aplicações Windows

Por predefinição, uma aplicação de ambiente de trabalho do SDK de Aplicações Windows pode ter várias instâncias em execução simultaneamente. Cada instância corre como um processo separado. Pode controlar este comportamento utilizando a classe Microsoft.Windows.AppLifecycle.AppInstance para registar instâncias, detetar as já existentes e redirecionar ativações.

Cenários para gestão de múltiplas instâncias

  • Aplicação por instância única — Redirecionar novas ativações para a instância já em execução.
  • Encaminhamento baseado em chaves — Encaminhe diferentes ficheiros ou URIs para instâncias específicas (por exemplo, uma instância por documento).
  • Descoberta de instâncias — Liste todas as instâncias em execução para coordenar o trabalho.

Registar uma instância através de uma chave

Utilize AppInstance.FindOrRegisterForKey no método Main da sua aplicação para reivindicar uma chave. Se a chave já estiver registada por outra instância, podes redirecionar a ativação. O método personalizado Main seguinte deve ser colocado em Program.cs, antes de qualquer inicialização de XAML:

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

Para usar um método personalizado Main , desative o ponto de entrada gerado automaticamente. No seu .csproj, defina <DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants> para acrescentar o símbolo sem sobrescrever definições existentes.

Impor comportamento de instância única

Para tornar a sua aplicação de instância única, use sempre a mesma chave:

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

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

Enumerar instâncias em execução

Use AppInstance.GetInstances() para descobrir todos os casos registados:

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

Desregistar uma instância

Quando a sua instância desliga, o registo é removido automaticamente. Também pode cancelar o registo explicitamente:

AppInstance.GetCurrent().UnregisterKey();

Diferenças face ao UWP de várias instâncias

Feature UWP SDK de aplicativos do Windows
Namespace Windows.ApplicationModel.AppInstance Microsoft.Windows.AppLifecycle.AppInstance
Requisito de manifesto Atributo SupportsMultipleInstances Não é obrigatório para aplicações de desktop
Descoberta de instâncias AppInstance.GetInstances() AppInstance.GetInstances() (mesmo padrão)
Redirecionamento de ativação AppInstance.RedirectActivationTo() AppInstance.RedirectActivationToAsync() (assíncrono)
Ponto de entrada principal personalizado Obrigatório Obrigatório (mesma abordagem)