views:

384

answers:

3

I have a program that only allows one instance of itself to run. I use this code

bool createdNew = true;
using(Mutex mutex = new Mutex(true, "MobilePOSServer", out createdNew))
{
    if(createdNew)
    {

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }
    else
    {
        Process current = Process.GetCurrentProcess();
        foreach(Process proc in Process.GetProcessesByName(current.ProcessName))
        {
            if(proc.Id != current.Id)
            {
                SetForegroundWindow(proc.MainWindowHandle);
            }
        }
    }
}

What I want to do is handle commandline arguments to call some start and stop methods on my MainForm winform. I can get the start just fine. But running the app from a new commandline window and trying to call a method is not working. I can get the window to come to the front. Is there a way I can get my form from the handle?

Or a better way to do this?

+1  A: 

You won't be able to get a reference to the form itself, no - that object exists in a different process.

If you want to be able to control the other process, it will need to expose some sort of "remote access" (where "remote" in this case means "out-of-process", not "on a different machine"). That could be via .NET remoting, WCF or your own simple protocol based on sockets, named pipes etc. However, it's likely to be a bit of a pain to do - so weigh up how much you really want this feature before you start putting too much work into it.

Jon Skeet
+2  A: 

Is this what you're looking for:

Single Instance Application, Passing Command Line Arguments

Jay Riggs
Dang Creating the single instance was easy. I didn't realize talking to it would be such a pain. Makes sense though. Thanks all. I just ended up calling exit on the process, we already had code to deal with the cleanup on form exit.
nportelli
+1  A: 

If the methods that you want to execute on the remote application are simple you could also use SendMessage/PostMessage to send a windows message to the other application and trigger operations to be executed.

If you really need more interaction with the other instance than a simple trigger, I would have to go with Jon's answer and I would pick WCF with named pipes. As he says, this is going to be a more involved solution and you should consider how important the feature really is to the application.

Brian ONeil