petko_stankoski
petko_stankoski

Reputation: 10713

Prevent the app to run twice, instead show the first window

I have a wpf app and I have to make the app to be run only once. There shouldnt be more than one instance on one machine.

Here's my code in App.xaml.cs, in the OnStartup() method:

var runningProcess = GetAnotherAppInstanceIfExists();

            if (runningProcess != null)
            {
                HandleMultipleInstances(runningProcess);
                Environment.Exit(0);
            }

public Process GetAnotherAppInstanceIfExists()
    {
        var currentProcess = Process.GetCurrentProcess();

        var appProcesses = new List<string> { "myApp", "myApp.vshost" };

        var allProcesses = Process.GetProcesses();

        var myAppProcess = (from process in allProcesses
            where process.Id != currentProcess.Id && appProcesses.Contains(process.ProcessName)
            select process).FirstOrDefault();

        if (myAppProcess != null)
        {
            return currentProcess;
        }

        return myAppProcess;
    }

public void HandleMultipleInstances(Process runningProcess)
    {
        SetForegroundWindow(runningProcess.MainWindowHandle);
        ShowWindow(runningProcess.MainWindowHandle, SW_RESTORE);
    }

So the app, when run for the second time, doesnt open a new instance, which is great. However, I need to find the first instance and show the window again, if it is minimized. This line is for that:

ShowWindow(runningProcess.MainWindowHandle, SW_RESTORE);

and it doesn't work. What am I doing wrong? I looked at a lot of examples online and my code is the same as them.

Upvotes: 1

Views: 1999

Answers (2)

A. Morel
A. Morel

Reputation: 10344

For me the solution was to do this:

change your App.xaml file's build action to Page. (right click on the file then properties => Build Action => dropdown to page)

in App.xaml.cs:

    private static readonly Mutex Mutex = new Mutex(true, "42ae83c2-03a0-472e-a2ea-41d69524a85b"); // GUI can be what you want !
    private static App _app;

    [STAThread]
    static void Main()
    {
        if (Mutex.WaitOne(TimeSpan.Zero, true))
        {
            _app = new App();
            _app.InitializeComponent();
            _app.Run();
            Mutex.ReleaseMutex();
        }
        else
        {
            //MessageBox.Show("You can only run one instance!");
            _app.MainWindow.WindowState = WindowState.Maximized;
        }
    }

Upvotes: 0

First change your App.xaml file's build action to Page. Then you can use this code snippet in App.xaml.cs :

private static readonly Mutex Mutex = new Mutex(true, "put your unique value here or GUID");
    private static MainWindow _mainWindow;       

    [STAThread]
    static void Main()
    {
        if (Mutex.WaitOne(TimeSpan.Zero, true))
        {
            var app = new App();
            _mainWindow = new MainWindow();
            app.Run(_mainWindow);
            Mutex.ReleaseMutex();
        }
        else
        {
            //MessageBox.Show("You can only run one instance!");
            _mainWindow.WindowState = WindowState.Maximized;
        }
    }

Upvotes: 1

Related Questions