I have a WPF desktop application that is MSIX-packaged using a Windows Application Package (WAP) project. I already know how to launch my WPF desktop app the first time using URI activation, by calling AppInstance.GetActivatedEventArgs()
and then analyzing the arguments:
if (activatedEventArgs.Kind == ActivationKind.Launch)
{
if (((LaunchActivatedEventArgs)activatedEventArgs).Arguments == "myactivationcode")
// .. do something
}
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. This doesn't happen with UWP apps, just desktop apps. I can kill the 2nd instance to follow a desired singleton pattern, but what I want is for the first instance of my WPF app to get some event that lets it know to come back into view.
Things I've researched that have no answers that I can see:
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? Any help here would be greatly appreciated.
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.
Whether a second instance is launched depends on the implementation of your custom Main
method.
In your second link, there is a link to blog post and a code example that demonstrates how to prevent another instance from being launched.
It uses named pipes to communicate with the already running app instance and passes a serialized IActivatedEventArgs
to it:
[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?
No
Or do I need to do some other form of IPC, like named pipes or WCF on the 2nd instance of my app?
Yes. Again, please refer to the mentioned blog post and accompanied code sample.