預設情況下,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 | 必要(採用相同方式) |