1

There is an option in my application to hide the window - form.hide(), and to put an notifyicon in the system tray, and when you click the notifyicon there will be a form.show().

If someone will try to run two instances of the app, I want a. not to run the new instance b. to show the window of the first instance

I already have a loop to check if a process with the same name exists. and I can tell the new app not to run ( return in the program.cs before Application.run(new form()))

but I yet have to tell the first app to show its main window.

I have the process (of the first instance) , i can get its handle its id etc.

the question How to show the window using it's process?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Eli Cohen
  • 131
  • 1
  • 10
  • For security purposes you do not want to check by process name because I can name my executable the same as yours to prevent your program from launching. Alternatively someone could rename a second file to launch your program twice. odyodyodys gave a good solution to this using mutex. – CodeCamper Jun 13 '13 at 22:33
  • a. I don't care if some one want to run 2 instances on purpose, I just don't want him to do it by mistake. b. I believe that in order to show the window of the first process, I will have anyway to catch the process. – Eli Cohen Jun 13 '13 at 22:41
  • @EliCohen no you don't have to. Check my answer. You simply need to "signal" the main process to show itself – Odys Jun 13 '13 at 22:43
  • Eli Cohen I have updated my answer to give you exactly what you wanted. Check it out. – CodeCamper Jun 14 '13 at 00:39

2 Answers2

0

For the first part of the question, here is what you can do. Add this in the Main before you show your form. The benefit of this is that you don't check by process name (which might not be unique), but you create a mutex which is somehow "global".

using (Mutex applicationMutex = new Mutex(true, "SomeRandomTextHere", out mutexCreated))
{
    if (!mutexCreated)
    {
        // Application is already running. Aborting..
        return;
    }

    // Application.Run(..)  goes here, plus other interesting stuff

}

For the second part of your question I would suggest the following:

  • Create a named event and set it initially to false. Then create a worker thread in your application that monitors this event. When it is signaled, Invoke your Show method from your main form.
  • Another approach is to search for the window handle of the main process and bring it to front. This article can give you ideas.

Bear in mind that doing a loop through all processes is not as efficient as using a mutex. If you don't care about speed, clean code and you just want this app to work then use this loop.. To me code is poetry.

Odys
  • 8,951
  • 10
  • 69
  • 111
  • I know nothing about Mutex, but that part is already done using a loop through all the processes, and checking if there is a process with the same name, the question is if there is such a process how to show it's window – Eli Cohen Jun 13 '13 at 22:33
  • Eli, You don't want to check by the process name because I can just rename my program the same as yours to prevent your program from launching or I can rename a second file of your program to launch it twice. If you know nothing of Mutex you should read http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx >> odyodyodys couldn't he create a second mutex in ` if (!mutexCreated) ` that the first program could check on a timer when it is minimized or something to that effect? – CodeCamper Jun 13 '13 at 22:36
  • @CodeCamper already edited my answer to include what you suggested.. Talk about timing! – Odys Jun 13 '13 at 22:41
  • I tried your another approach (from the article) and it's not working, I tried SetForegroundWindow(hWnd) and ShowWindow(hWnd, 5) in my case the window is hidden (there is only a notifyicon) – Eli Cohen Jun 13 '13 at 23:30
  • Eli Cohen just use my code below Program 1 will be when your program is minimized and Program 2 code will be launched if the program is already open. I will edit my post to try to give another example. – CodeCamper Jun 13 '13 at 23:53
  • thanks everybody, I am sure all you wrote will work, I chose the approach of the one who found my question is a duplicate. it's great and simple. – Eli Cohen Jun 14 '13 at 13:37
0

Rewrote the code just for you this will give you exactly what you want. It will check for duplicates and focus the screen when a duplicate is opened.

        EventWaitHandle ProgramOpen = new EventWaitHandle(false, EventResetMode.ManualReset, "ProgramOpen198472");
        EventWaitHandle FocusProgram = new EventWaitHandle(false, EventResetMode.ManualReset, "FocusMyProgram198472");
        private delegate void focusConfirmed(); Thread FocusCheck; 
        private void focus() { FocusProgram.WaitOne(); this.Invoke(new focusConfirmed(()=>{this.Show(); this.BringToFront();}));}
        private void Form1_Load(object sender, EventArgs e)
        {
            if (ProgramOpen.WaitOne(0))
            {
                FocusProgram.Set();
                this.Close();
            }
            ProgramOpen.Set();
        }

        private void HideButton_Click(object sender, EventArgs e)
        {
            this.Hide();
            FocusProgram.Reset();
            FocusCheck = new Thread(focus);
            FocusCheck.Start();
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FocusProgram.Set();
        }
CodeCamper
  • 6,609
  • 6
  • 44
  • 94
  • an example is very important for me. i do my best to understand what odyodyodys wrote, but why 2 winforms? it has to 2 instances of 1 winform. – Eli Cohen Jun 13 '13 at 23:08
  • Because I do not have your particular program I made 2 separate programs to test the functionality of sending a signal to 2 different processes to demonstrate how you can send commands to another process that are predetermined such as showing the form. You just replace MessageBox with whatever you want to do. Rather than have 2 forms you will have the same code in your one program. Use an if to check is the form is already open and if it is call the Program 2 code. I will try to update the code to give you an even clearer idea. – CodeCamper Jun 13 '13 at 23:51