使用 Windows 應用程式 SDK 的多執行個體應用程式

預設情況下,Windows 應用程式 SDK 桌面應用程式可以同時執行多個實例。 每個實例都作為獨立的程序執行。 你可以使用 Microsoft.Windows.AppLifecycle.AppInstance 類別來控制此行為,以註冊執行個體、偵測現有的執行個體,並重新導向啟動。

多實例管理的情境

  • 單一實例強制執行 — 將新啟用重新導向已執行的實例。
  • 基於金鑰的路由 — 將不同檔案或 URI 路由到特定實例(例如,每份文件一個實例)。
  • 實例發現 — 列舉所有正在執行的實例以協調工作。

用金鑰註冊實例

在您的應用程式的 Main 方法中使用 AppInstance.FindOrRegisterForKey 來取得金鑰。 如果金鑰已經被其他實例註冊,你可以重新導向啟用。 下列自訂 Main 方法應放在 Program.cs 中,且位於任何 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

若要使用自訂 Main 方法,請關閉自動產生的入口點。 在你的 .csproj中,設定 <DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants> 為附加符號且不覆蓋現有定義。

強制執行單一實例行為

要讓你的應用程式成為單一實例,請始終使用相同的鍵:

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

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

列舉執行實例

使用 AppInstance.GetInstances() 以查找所有註冊的實例:

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

取消註冊一個實例

當您的執行個體關閉時,註冊資料會自動移除。 您也可以明確取消註冊:

AppInstance.GetCurrent().UnregisterKey();

與 UWP 多實例的差異

Feature UWP Windows 應用程式 SDK
命名空間 Windows.ApplicationModel.AppInstance Microsoft.Windows.AppLifecycle.AppInstance
清單要求 SupportsMultipleInstances 屬性 桌面應用程式不需使用
執行個體探索 AppInstance.GetInstances() AppInstance.GetInstances() (同樣的模式)
啟動重定向 AppInstance.RedirectActivationTo() AppInstance.RedirectActivationToAsync() (非同步)
自訂主要入口 Required 必要(採用相同方式)