0

I am creating a WinForm application (.Net-5, .Net Core). The instance of my WinForm could be minimized/Hidden. Whenever I start my application, I need to check if there is an existing instance of the application already running. If there is already an existing instance then, I need to display its WinForm instead of creating new one.

In the code below, I am always checking if there is an existing process. If yes, how can I display open its Form/GUI?

    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        var runningProcess = System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location));
       
        if (runningProcess.Length>1) // Already running processes
        {
            //Get our previous instance
            Process myProcess = runningProcess[0];

            //How to SHOW the already exisitng (but minimized) instance of the Form?
            //--?
            //--?

        }
        else
        {
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MyGUI());
        }
    }
skm
  • 5,015
  • 8
  • 43
  • 104
  • @user9938 : The useful part from the link is to use the code `SetForegroundWindow(process.MainWindowHandle);`. I tried to use it but it does not bring the hidden window of my previous instance to front. So, not working for me :( – skm Sep 03 '22 at 19:19
  • See the `RestoreWindow()` method [here](https://stackoverflow.com/a/71589883/7444103) + `BringWindowToTop()` – Jimi Sep 03 '22 at 19:39
  • Back in the Win32 time frame, I worked on a multi app suite. We wanted only one instance of any app running and we wanted some other interapp communication. We used the COM running object table to manage all this. At startup, we'd check if there was another instance of the app running, if so, we'd tell it how we were called. That instance would pop to the front and respond to the startup info. If no other instance was running, we'd register the current instance. We'd unregister when we closed. Take a look at https://stackoverflow.com/questions/11835617/understanding-the-running-object-table – Flydog57 Sep 03 '22 at 19:52
  • https://stackoverflow.com/questions/697058/single-instance-windows-forms-application-and-how-to-get-reference-on-it/699701#699701 – Hans Passant Sep 04 '22 at 00:08
  • .NET 5 is no longer supported. See [here](https://learn.microsoft.com/en-us/lifecycle/products/microsoft-net-and-net-core) for more information. – Tu deschizi eu inchid Sep 04 '22 at 13:54

1 Answers1

-1

.NET 5 is no longer supported. See here for more information. You may consider moving your project to .NET 6.

The following shows a way to ensure only a single instance of one's Windows Forms App is running. If it's minimized or hidden it'll be shown. The code has been tested with a new Windows Forms App project (.NET 6) on Windows 10.

In the code below, when the form is hidden, p.MainWindowHandle is IntPtr.Zero. Therefore, it's necessary to find the window handle another way. I've used FindWindowA which uses the window title to find the desired window as described here. Form1 is the default form that exists when one creates a new Windows Forms project - the form's window text "Form1" should be changed to your desired window title.

Program.cs:

using System.Runtime.InteropServices;
using System.Diagnostics;

namespace TestAllowSingleInstance
{
    internal static class Program
    {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            [DllImport("user32.dll", SetLastError = true)]
            static extern IntPtr FindWindowA(string? lpClassName, string lpWindowName);

            [DllImport("user32.dll")]
            static extern bool IsIconic(IntPtr hWnd);

            [DllImport("user32.dll")]
            static extern IntPtr SetFocus(IntPtr hWnd);

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

            //sets window's show state - doesn't wait for operation to complete
            [DllImport("user32.dll")]
            static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

            using (Process curProcess = Process.GetCurrentProcess())
            {
                foreach (Process p in Process.GetProcessesByName(curProcess.ProcessName))
                {
                    if (p.Id != curProcess.Id && p.MainModule?.FileName == curProcess.MainModule?.FileName)
                    {
                        //set as foreground (ie: show on top of other windows)
                        SetForegroundWindow(p.MainWindowHandle);

                        if (IsIconic(p.MainWindowHandle))
                        {
                            //minimized
                            ShowWindowAsync(p.MainWindowHandle, 9); //SW_RESTORE = 9
                        }
                        else
                        {
                            IntPtr hwnd = p.MainWindowHandle;

                            //when the window is hidden, the MainWindowHandle = IntPtr.Zero
                            if (p.MainWindowHandle == IntPtr.Zero)
                            {
                                //window is hidden, find it by the title

                                //"Form1" is the title that is displayed on the Window
                                hwnd = FindWindowA(null, "Form1");
                            }

                            ShowWindowAsync(hwnd, 1); //SW_SHOWNORMAL = 1; SW_SHOWMAXIMIZED = 3
                        }

                        //set focus
                        SetFocus(p.MainWindowHandle);

                        Environment.Exit(0);
                    }
                }
            }

            // To customize application configuration such as set high DPI settings or default font,
            // see https://aka.ms/applicationconfiguration.
            ApplicationConfiguration.Initialize();
            Application.Run(new Form1());
        }
    }
}

Resources:

Tu deschizi eu inchid
  • 4,117
  • 3
  • 13
  • 24