Soul Reaver
Soul Reaver

Reputation: 2092

How to check if there are other application instances running

I've written an application in C#, which is placed on our server. When someone needs to use it, the application is started directly from the server, from any connected PC in our LAN.

Is there any easy way, to check how many instances are running ? Or rather, if there is any other instance than the one started by me ?


Edit:

this is not a duplicate of provided post, because I don't want to make sure, that there is only one instance running (as in "don't run more than 1 app at the same time") but to just check, if someone other than me is running it (in normal situations it has to work at the same time on more than one PC)

Upvotes: 1

Views: 2290

Answers (3)

Zdeslav Vojkovic
Zdeslav Vojkovic

Reputation: 14591

In general, to allow only N concurrent instances of an application, you can used named semaphores as they are visible across the system.

When you start the application, try to create a named Semaphore with arguments specifying the allowed number of instances. if WaitOne fails, this means that all instances are in use, so you exit the application.

Here's the example code (of top of my head, glossing over some subtle issues, no error handling, etc)

    const int MAX_INSTANCES = 2; // set desired number of concurrent instances
    var s = new Semaphore(MAX_INSTANCES, MAX_INSTANCES, "unique_name_of_semaphore");
    if (s.WaitOne(0)) // zero timeout - exit immediately if exhausted
    {
      // good, we're in, run the app
      Application.Run(new Form()); // run the app - a winforms example
      s.Release();   // release the semaphore
    }
    else
    {
      // oops, exhausted:
      MessageBox.Show("too many instances running !!");
    }

You can also use variations with Semaphore.OpenExisting(), depending on your app needs.

EDIT: oops, just noticed that you actually don't need this but to verify instances running on different machines - this is harder without having a mechanism to report to server.

Upvotes: 0

Ken Kin
Ken Kin

Reputation: 4713

There are several ways to do, for example, something using sockets, database. A simplest way(but not as safe) to do, might be using a file to record the count of instances, you might want to improve it.

void WriteToFile(int x, int millisecondsTimeout) {
    for(; ; Thread.Sleep(millisecondsTimeout))
        try {
            using(var file=File.Open("instances.bin", FileMode.OpenOrCreate)) {
                var bytes=new byte[sizeof(int)];
                file.Read(bytes, 0, sizeof(int));
                var instances=x+BitConverter.ToInt32(bytes, 0);

                if(instances>-1)
                    file.Write(BitConverter.GetBytes(instances), 0, sizeof(int));

                break;
            }
        }
        catch(IOException ex) {
        }
}

void Increment() { // invoke on program starts
    WriteToFile(1, 1000);
}

void Decrement() { // invoke on program exits
    WriteToFile(-1, 1000);
}

Note the file "instances.bin" should be a file located on the server.

You might also want to write a AppDomain.CurrentDomain.UnhandledException handler once your program terminated unexpectedly.

Upvotes: 0

Alexei Levenkov
Alexei Levenkov

Reputation: 100630

There is no easy way to know that instance of a program runs on some machine from the same binaries - you program need to somehow report "I'm running" to some shared location where than it can check if there are other instances running.

If you only need to check for single instance it may be possible to open a file from the same location and it will fail if multiple instances try to open it.

Couple options for shared location to count instances:

  • update some file with name of machine
  • some web service/site to ping
  • shared DB

Note that it also means if program dies there may not be report in the shared location about this particular instance finished.

Upvotes: 1

Related Questions