Call me igris
Call me igris

Reputation: 1

How to fix the Single Instance for my Wpf .NET 6 application?

I'm trying to bring up the main window when trying to reopen the app, it works when it's in a background or minimized state but it doesn't work when the window is in a hidden state!

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;

namespace SingleInstanceTest
{
    public partial class Program
    {
        private static Mutex? _mutex;

        [STAThread]
        public static void Main()
        {
            u_mutex = new Mutex(true, GetApplicationMutexName(), out var isNewInstance);
            if (isNewInstance)
            {
                var app = new App();
                app.InitializeComponent();
                app.Run();

                app.Exit += (sender, e) =>
                {
                    _mutex.ReleaseMutex();
                    _mutex.Dispose();
                };
            }
            else
            {
                // var handle = NativeMethods.FindWindow(null, "MainWindow");
                // if (handle != IntPtr.Zero)
                // {
                //     if (NativeMethods.IsIconic(handle))
                //     {
                //         // NativeMethods.SendMessage(handle, NativeMethods.WM_SYSCOMMAND, (IntPtr)NativeMethods.SC_RESTORE, (IntPtr)0);
                //         NativeMethods.ShowWindowAsync(handle, WindowShowStyle.Restore);
                //     }
                //     NativeMethods.SetForegroundWindow(handle);
                // }
                var firstInstanceProcess = GetFirstInstanceProcess();
                if (firstInstanceProcess != null)
                {
                    if (NativeMethods.IsIconic(firstInstanceProcess.MainWindowHandle))
                    {
                        // NativeMethods.SendMessage(firstInstanceProcess.MainWindowHandle, NativeMethods.WM_SYSCOMMAND, (IntPtr)NativeMethods.SC_RESTORE, (IntPtr)0);
                        NativeMethods.ShowWindowAsync(firstInstanceProcess.MainWindowHandle, WindowShowStyle.Restore);
                    }
                    NativeMethods.SetForegroundWindow(firstInstanceProcess.MainWindowHandle);
                }
            }
        }

        private static string GetApplicationMutexName()
        {
            return $"Global\\{Assembly.GetExecutingAssembly().GetType().GUID}";
        }

        private static Process? GetFirstInstanceProcess()
        {
            var currentProcess = Process.GetCurrentProcess();
            var processes = Process.GetProcessesByName(currentProcess.ProcessName);
            foreach (var process in processes)
            {
                if (process.Id != currentProcess.Id)
                {
                    return process;
                }
            }
            return null;
        }
    }

    internal static class NativeMethods
    {
        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_RESTORE = 0xF120;

        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShowWindow(IntPtr hWnd, WindowShowStyle nCmdShow);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsIconic(IntPtr hWnd);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShowWindowAsync(IntPtr hWnd, WindowShowStyle nCmdShow);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindowInternal(IntPtr hWnd);
    }

    internal enum WindowShowStyle : uint
    {
        Hide = 0,
        ShowNormal = 1,
        ShowMinimized = 2,
        ShowMaximized = 3,
        Maximize = 3,
        ShowNormalNoActivate = 4,
        Show = 5,
        Minimize = 6,
        ShowMinNoActivate = 7,
        ShowNoActivate = 8,
        Restore = 9,
        ShowDefault = 10,
        ForceMinimized = 11
    }
}

Does anyone have a solution to my problem or a complete library for Single Instance like what is available in .NET Framework, as on my test on this application https://github.com/IgrisModz/WPFSingleInstance/tree/master ?

PS: I had tried with SingleInstanceCore as I'm using .NET 6 but couldn't find how to get the desired behavior.

Upvotes: 0

Views: 501

Answers (1)

Call me igris
Call me igris

Reputation: 1

I was able to find what I was looking for via this library: https://github.com/novotnyllc/SingleInstanceHelper/tree/master

I also had this sample: https://github.com/gerardo-lijs/SingleInstance-WPF-Sample it worked but didn't really fit my needs

Upvotes: 0

Related Questions