Bring forward an already open program - C#

Asked

Viewed 591 times

1

I have a program that, when trying to run, and is already open, it sends a message that it is already running, but, I wanted to know a way to bring the program forward when I try to open it.

Code:

    class InicializaPrograma
    {
        static System.Threading.Mutex _mutex = new System.Threading.Mutex(true, name: "7d89086c-8e9f-43c8-8acd-d8cf877f48ca");

        [System.STAThread]
        static void Main()
        {
            if (_mutex.WaitOne(System.TimeSpan.Zero, true))
                try
                {
                    System.Windows.Forms.Application.EnableVisualStyles();
                    System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
                    System.Windows.Forms.Application.Run(new Programa());
                }
                finally { _mutex.ReleaseMutex(); }
            else System.Windows.Forms.MessageBox.Show("Já existe um Gerador de Deck aberto.", "Gerador de Deck", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
        }
    }

For example, if the program is open, the GUID is checked, and brings the corresponding program forward...

1 answer

3


whereas:

  1. Application instance "A" running.

  2. Open a new instance "B".

  3. Instance "B" checks whether another instance is already running.

  4. Positive result, "A" is running.

  5. Closes instance "B".

You want the "A" instance to be put in the foreground or to restore the window if it is minimized before closing the "B" instance.

As instance "B" has no control over instance "A", and "A" does not know the attempt to open "B", you need to use the Windows API so that instance "B" can bring A forward.

Example 1:

static class Program
{

     [System.Runtime.InteropServices.DllImport("user32.dll")]
     public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);

    [System.STAThread]
    static void Main()
    {
        if (_mutex.WaitOne(System.TimeSpan.Zero, true))
        { 
            try
            {
                System.Windows.Forms.Application.EnableVisualStyles();
                System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
                System.Windows.Forms.Application.Run(new Programa());
            }
            finally { _mutex.ReleaseMutex(); }
        }
        else
        {
            System.Windows.Forms.MessageBox.Show("Já existe um Gerador de Deck aberto.", "Gerador de Deck", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);

            System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();
            System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(p.ProcessName);
            foreach (System.Diagnostics.Process pp in ps)
            {
                if (pp.Id != p.Id)
                {
                    Program.SwitchToThisWindow(pp.MainWindowHandle, true);
                }
            }


        }
    }
}

Example 2:

static class Program
{

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

    [System.STAThread]
    static void Main()
    {
        if (_mutex.WaitOne(System.TimeSpan.Zero, true))
        { 
            try
            {
                System.Windows.Forms.Application.EnableVisualStyles();
                System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
                System.Windows.Forms.Application.Run(new Programa());
            }
            finally { _mutex.ReleaseMutex(); }
        }
        else
        {
            System.Windows.Forms.MessageBox.Show("Já existe um Gerador de Deck aberto.", "Gerador de Deck", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);

            System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();
            System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(p.ProcessName);
            foreach (System.Diagnostics.Process pp in ps)
            {
                if (pp.Id != p.Id)
                {
                    Program.SetForegroundWindow(pp.MainWindowHandle);
                }
            }


        }
    }
}

Sorry if you got a little confused with these "A" /"B", rsrs the first example, is how I’ve used.

The second, I found here: http://www.webskaper.no/wst/creatingasingleinstanceapplicationinc-aspx/

There is a detail that you test if there is another instance by the GUID, while to achieve the MainWindowHandle we need the process name. The function will not work if the second instance is a copy of the executable with another name.

Details about the functions SetForegroundWindow and SwitchToThisWindow: https://stackoverflow.com/a/12203109/4713574

I hope it helps.

  • 1

    Very good! The first tip worked perfectly :) Note: I had to replace "Program.Switchtothiswindow(pp.Mainwindowhandle, true);" for "Switchtothiswindow(pp.Mainwindowhandle, true);" Thank you very much! <3

  • right, in the example I use a static class Program, so the difference. But all right, thank you =]

  • 1

    Ahh yes, I haven’t seen huehuehueh If you want to watch, I’m doing a program in C#, as you like C# :v https://github.com/lucasnaja/deckgenerator

Browser other questions tagged

You are not signed in. Login or sign up in order to post.