views:

227

answers:

3

Okay, I have this program and I don't want more than one instance of it running. So what I have right now is it grabs all instances that match it's name, and if there are more than one it quits and lets the user know it's already running in another instance.

However, there is a special case in which the new instance will want change what the other instance is doing, then it will exit. How can I do this?

Here's an example: I have this program that times an event. I don't want more than one running at the same time because you can't be doing two things at once (for this application). Now say a third party program wants to notify this thread that the user is now working on something else, so it launches the application again. If the application is already running, it will update it's actions, else it will act as normal.

How can this be done?

This is what I use to tell if there is another instance running:

            string proc = Process.GetCurrentProcess().ProcessName;

            Process[] processess = Process.GetProcessesByName(proc);
            if (processess.Length > 1) {
                MessageBox.Show("There is an instance of the Timer already running");
                return;
            }
+1  A: 

You can use a shared (named) mutex for this.

See the Win32 API documentation for Mutex objects (I assume C# has language bindings for this).

frankodwyer
see my updated answer...I'm assuming you're running on Windows. Other OSes have similar IPC services.
frankodwyer
+2  A: 

The thing that complicates this is the fact that you want, in certain conditions, to allow a second invocation of the program to do something if another one is running. Using the named mutex will allow you to detect whether the program is already running -- it should be holding the mutex already. You will still need a way to communicate with it to tell the running program to do something when the second one runs. An asynchronous message queue would probably work, you'd just need to have the running program check it periodically to see if there are any new messages waiting. The message would need to tell the program how to change. Look at the System.Threading namespace (since it looks like you're using .Net already), in particular the mutex and semaphore classes, and System.Messaging.MessageQueue for message exchange.

The basic idea is:

  program start
  try to acquire mutex (or semaphore)
  if failed
     send message via message queue to running program
     exit
  else

  set up listener for message queue

  run rest of program

The listener could take the form of a timer that expires periodically with the expiration callback checking for messages in the queue and updating the program actions accordingly. The timer would need to autoreset so that it would go back to listening. Your program will need the ability to recover from being interrupted by the timer and "restart" based on the updated configuration.

tvanfosson
Shouldn't named pipes be able to take care of the messaging?
configurator
I suppose so, hadn't really thought about it.
tvanfosson
A: 

Your best bet is going with a Mutex for detection, and then using very trivial remoting via an IPCChannel.

All it takes is 1 MarshalByRefObject class and starting the remoting services when starting the app initially.

leppie