启动后如何检测 WPF 桌面包 (WAP) 上的 URI 激活?

How to detect URI activation on a WPF desktop package (WAP) after it has already launched?

我有一个 WPF 桌面应用程序,它是使用 Windows 应用程序包 (WAP) 项目进行 MSIX 打包的。我已经知道如何在第一次使用 URI 激活时启动我的 WPF 桌面应用程序,方法是调用 AppInstance.GetActivatedEventArgs() 然后分析参数:

if (activatedEventArgs.Kind == ActivationKind.Launch)
{
    if (((LaunchActivatedEventArgs)activatedEventArgs).Arguments == "myactivationcode")
        // .. do something
}

但是如果用户第二次运行 URI 激活,而我的应用程序已经启动,我了解到我的应用程序的一个新实例已启动。这不会发生在 UWP 应用程序上,只是桌面应用程序。我可以杀死第二个实例以遵循所需的单例模式,但我想要的是让我的 WPF 应用程序的第一个实例获得一些事件,让它知道重新进入视图。

我研究过但没有答案的事情:

  1. https://docs.microsoft.com/en-us/windows/uwp/launch-resume/handle-uri-activation#step-3-handle-the-activated-event

URI 重新激活是否存在任何此类 API 或事件?或者我是否需要在我的应用程序的第二个实例上执行其他形式的 IPC,例如命名管道或 WCF?如有任何帮助,我们将不胜感激。

But if a user runs the URI activation a 2nd time, while my app is already launched, I have learned that a new instance of my app is launched.

是否启动第二个实例取决于您的自定义 Main 方法的实现。

在您的 , there is a link to blog post and a code example 中演示了如何防止启动另一个实例。

它使用命名管道与已经 运行 的应用程序实例进行通信,并将序列化的 IActivatedEventArgs 传递给它:

[STAThread]
static void Main(string[] args)
{
    IActivatedEventArgs activatedEventArgs = AppInstance.GetActivatedEventArgs();
    using (Mutex mutex = new Mutex(false, AppUniqueGuid))
    {
        if (mutex.WaitOne(0, false))
        {
            new Thread(CreateNamedPipeServer) { IsBackground = true }
                .Start();

            s_application = new App();
            s_application.InitializeComponent();
            if (activatedEventArgs != null)
                s_application.OnProtocolActivated(activatedEventArgs);
            s_application.Run();
        }
        else if (activatedEventArgs != null)
        {
            //instance already running
            using (NamedPipeClientStream namedPipeClientStream
                = new NamedPipeClientStream(NamedPipeServerName, AppUniqueGuid, PipeDirection.Out))
            {
                try
                {
                    namedPipeClientStream.Connect(s_connectionTimeout);
                    SerializableActivatedEventArgs serializableActivatedEventArgs = Serializer.Serialize(activatedEventArgs);
                    s_formatter.Serialize(namedPipeClientStream, serializableActivatedEventArgs);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, string.Empty, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
    }
}

Does any such API or event exist for URI re-activation?

没有

Or do I need to do some other form of IPC, like named pipes or WCF on the 2nd instance of my app?

是的。同样,请参考提到的博客 post 和随附的代码示例。