0

I am trying to build a single instance WPF app using c#. I follow this answer to create the following app. However, the OnStartupNextInstance function never gets called no matter how many times I re-launch the same app (double-clicking the *.exe file).

There is no exceptions or anything printed in the Debug Output.

Has anyone got a single instance WPF app working using this approach? What am I missing here?

using Microsoft.VisualBasic.ApplicationServices;
using System;
using System.Windows;

namespace WpfApp1
{
    public class EntryPoint
    {
        [STAThread]
        public static void Main(string[] args)
        {
            var man = new SingleInstanceManager();
            man.Run(args);
        }
    }

    public class SingleInstanceManager : Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
    {
        public SingleInstanceManager()
        {
            IsSingleInstance = true;
        }

        protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs eventArgs)
        {
            MessageBox.Show("First time launch");
            var app = new App();
            app.InitializeComponent();
            app.Run();
            return false;
        }

        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
        {
            MessageBox.Show("Subsequent launch");
            base.OnStartupNextInstance(eventArgs);
            eventArgs.BringToForeground = true;
        }
    }
}
Believe2014
  • 3,894
  • 2
  • 26
  • 46
  • In your link, it suggests to use a method `public void Activate()` which Activates the MainWindow (and call it in `OnStartupNextInstance`), Could that be relevant? Also you could try putting a breakpoint on the first line of `OnStartupNextInstance` and check with debugging mode if your code reaches there at all. – Keyur PATEL Jun 14 '17 at 03:26
  • Are you sure you're debugging the correct instance? The `OnStartupNextInstance()` method is called only in the original process, not the new one. Note the `MessageBox.Show()`. You should see that message box launching subsequent instances, and there's nothing in the code you posted to suggest anything different would happen. Are you sure the code you posted is in fact the code you're running? – Peter Duniho Jun 14 '17 at 03:28
  • @KeyurPATEL WPF app does not have the Activate function :( – Believe2014 Jun 14 '17 at 12:34
  • @PeterDuniho this is the exact code that I am running. The App object is a WPF app, which has a StartupUri set to MainWindow. I do see the MainWindow show up after the MessageBox. I also put break points and use Debug > New Instance menu in Visual Studio to step through each line of the posted code every new and subsequent instance. I couldn't explain why the code didn't work last night. But then, it works perfectly this morning. I did restart my computer in the morning before retry. Maybe that helped. – Believe2014 Jun 14 '17 at 12:38

2 Answers2

1

You aren't setting MainForm in SingleInstanceManager, and you don't need to new App().Run().

Try:

    public class SingleInstanceManager : WindowsFormsApplicationBase
    {
        public SingleInstanceManager()
        {
            IsSingleInstance = true;
            MainForm = new MyMainForm();
        }

        protected override bool OnStartup(StartupEventArgs eventArgs)
        {
            MessageBox.Show("First time launch");
            return base.OnStartup(eventArgs);
        }

        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
        {
            MessageBox.Show("Subsequent launch");
            base.OnStartupNextInstance(eventArgs);
            eventArgs.BringToForeground = true;
        }
    }
swooby
  • 3,005
  • 2
  • 36
  • 43
  • This works great, but the same EXE invoked from different folder should not be considered as single instance. How do we fix that? – Anand Mar 11 '19 at 16:35
  • I suspect that would require your own global mutex checking and would not be directly supported by WindowsFormsApplicationBase. It might be up to the runtime business logic to decide if a different app path/version/hash is the same instance or not (ex: Updating app, 2nd instance is command-line only when first is UI, etc). You might glance at the code from WindowsFormsApplicationBase and implement your own: https://github.com/rashiph/DecompliedDotNetLibraries/blob/master/Microsoft.VisualBasic/Microsoft/VisualBasic/ApplicationServices/WindowsFormsApplicationBase.cs – swooby Mar 12 '19 at 20:33
0
  • Build your application.
  • Right-click on your project in the Solution Explorer in Visual Studio and choose "Open Folder in File Explorer".
  • Browse to the bin/Debug (or bin/Release if you built the application in release mode) folder.
  • Double-click on the executable (.exe). You should then see a MessageBox saying "First time launch".
  • Now, without closing the MessageBox, double-click on the same .exe again. This should pop up the "Subsequent launch" MessageBox.

Note that if you close the application, you will see the "First time launch" message pop again when you start another instance. It is only when there is another instance currently running that the OnStartupNextInstance will be called.

mm8
  • 163,881
  • 10
  • 57
  • 88