tags:

views:

617

answers:

4

I'd like to create a simple singleton commandline application (a service?) in C# that when it was run, it checked to see if it was already running, and if so, it passed the command-line args to the already running instance and closed itself. Now in the already running instance it would receive the command-line args through an event like "delegate void Command(string[] args);" or something like that, so I can manage command-line through one application via events.

For instance in photoshop, when you open a picture for the first time, it loads a new instance photoshop, but when you open a second picture, it checks to see if an instance of photoshop is already running, and if it is, it passes the picture to the already loaded instance of photoshop so it can avoid the costly load-time of photoshop all over again...

Or in the web browser, you can set it so if you open a new .html file, it opens it up in a new tab, not a new window instance.

or many text editors have settings to only allow one instance of the text editor open and when a new file is opened, it's loaded in a new tab, not a new window...

many music players like winamp do this too...

I am going to eventually be setting this up as a service, so it should be constantly listening for command-line args later, but for now it's mostly so that I can manage the opening of files of a specific type together in one singleton application, or have other applications pass command-line arguments of files they want to be opened...

Also, if you know a better way or an api in .Net to re-rout all command-line args passed, to an event of a service that is always running, I can work with that... but I'd also like to keep this cross-platform so it can run in Linux/Mac on Mono if that's possible, without having to manage two or more code-bases...

A: 

We did something simillar using although for a very different purpose using .net remoting on 1.0 / 1.1 framework. Basically we'd use a semaphore to ensure we were the only running instance. You'll want to target the global namespace, if you want to have only one instance per machine or the local if you want one per user session (In terminal service and fast user switching scenarios).

If you can lock the semphore, you will setup remoting and start listening for events, and then continue on with your code.

if you can't lock then you can asssume you have another running instance in which case you'll open up a remoting channel to the other instance pass the args and shutdown.

JoshBerke
A: 

You could try using a named mutex (naming it will make it system wide, and easily identifiable). With the mutex, you can either run the instance (if no mutex exists with the name), or you can open the existing instance and pass in your parameters. Apologies for no code sample, writing this from my phone.

Edit: nvrmnd. Just reread the post, and I don't think this will work for you going cross platform.

A: 

Visual basic has this built-in. Take a look at:

Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase -- Public Event StartupNextInstance

Jonathan Allen
Microsoft.VisualBasic is Evil!!! ;)
Keivan
+2  A: 

This is the article i used to implement the exact functionality that you are looking for, it allows you to transfer command line arguments as well.

Single-Instance C# Application - for .NET 2.0

Keivan