在 OnLaunched 中处理单例
打开App.xaml.cs
文件,编辑OnLaunched
方法
protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
var mainInstance = Microsoft.Windows.AppLifecycle.AppInstance.FindOrRegisterForKey("hello");
if (mainInstance.IsCurrent)
{
mainInstance.Activated += MainInstance_Activated;
} else
{
var activatedEventArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
await mainInstance.RedirectActivationToAsync(activatedEventArgs);
Process.GetCurrentProcess().Kill();
return;
}
m_window = new MainWindow();
m_window.Activate();
}
private void MainInstance_Activated(object sender, Microsoft.Windows.AppLifecycle.AppActivationArguments e)
{
PInvoke.User32.MessageBox(IntPtr.Zero, "Activated", "Single instanced", PInvoke.User32.MessageBoxOptions.MB_OK);
}
通过 AppInstance.FindOrRegisterForKey 方法查找或创建一个实例。
然后通过 AppInstance.IsCurrent 属性检测是否为当前实例。
当检测到已经注册过实例时可以考虑用 RedirectActivationToAsync 来激活主实例。
当第2次运行程序时,主实例的MainInstance_Activated
方法将被调用。
在 Main 中处理单例
写过C/C++语言的都知道,程序的入口函数是main
函数,如果在main
中检测程序实例将会更及时。
编辑工程文件,加入DISABLE_XAML_GENERATED_MAIN
宏
<DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants>
再次编译程序,会得到一个编译错误
CSC : error CS5001: 程序不包含适合于入口点的静态 "Main" 方法
因为DISABLE_XAML_GENERATED_MAIN
宏会禁止系统生成Main
方法,所以我们就需要手写一个入口函数。
新建一个Program.cs
文件,并写入以下代码
using Microsoft.UI.Xaml;
using Microsoft.Windows.AppLifecycle;
using System;
namespace MyApp
{
internal static class Program
{
[STAThread]
static void Main(string[] args)
{
WinRT.ComWrappersSupport.InitializeComWrappers();
bool isRedirect = DecideRedirection();
if (!isRedirect)
{
Application.Start(_ => new App());
}
}
private static bool DecideRedirection()
{
bool isRedirect = false;
AppInstance keyInstance = AppInstance.FindOrRegisterForKey("randomKey");
if (keyInstance.IsCurrent)
{
keyInstance.Activated += OnActivated;
}
else
{
isRedirect = true;
AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs();
keyInstance.RedirectActivationToAsync(args).AsTask().Wait();
}
return isRedirect;
}
private static void OnActivated(object sender, AppActivationArguments args)
{
PInvoke.User32.MessageBox(IntPtr.Zero, "Activated", "Single instanced", PInvoke.User32.MessageBoxOptions.MB_OK);
}
}
}
所以实现程序单例的方法核心就在 AppInstance 这个类中。
相关阅读
应用程序生命周期功能迁移
Making the app single-instanced
A Minimal UWP App
Multiple instances support for UWP apps