3

I'm trying to make a console app in c# that will confirm that another application is always running. The other application periodically crashes, and I need to check every few minutes and relaunch it if it has stopped working.

There are many questions on SO that address making sure than no more than one instance of the application is running. I'm trying to confirm that one (no more or less) is running at all times.

Does anybody know how to even begin approaching this?

tshepang
  • 12,111
  • 21
  • 91
  • 136
carlbenson
  • 3,177
  • 5
  • 35
  • 54
  • 1
    http://stackoverflow.com/questions/1742787/check-if-a-specific-exe-file-is-running might be relevant to your question. At least, it has the code for getting process list by process name. – Sergey Kudriavtsev Oct 07 '11 at 13:51
  • Can you call some method or something on the application you are watching? But why is that application crashing? Don't you need to solve that issue before your are worrying about this stuff...solve the problems at the root if you can. – Bas Slagter Oct 07 '11 at 13:52
  • @Baszz -- A valid point, but even the most well-written program will crash if left on for long enough. – carlbenson Oct 07 '11 at 13:56
  • It's common to make process-watcher scripts with shell (command-line) utilities like tasklist.exe or pslist.exe, rather than make an executable just for the task. Or for a more .NET-ish option, a PowerShell script could use `Get-Process`... – ewall Oct 07 '11 at 13:57
  • @Carl - you're right of course, every application has bugs no matter how well written. A well written app should be able to run for years without failure though. Attach a debugger to it and find out why it's crashing if it's happening often enough to be a concern. – Russell Troywest Oct 07 '11 at 14:05

5 Answers5

7

I would suggest using System.Diagnostics.Process.GetProcessesByName to see if your process is running and then, if not, using System.Diagnostics.Process.Start to start the process.

var processes = Process.GetProcessesByName("yourProcessName");

if(processes.Length == 0)
{
    Process.Start(@"C:\Path\To\Your\Process.exe");
}

// Kill the extras
for(int i = 1; i < process.Length; i++)
{
    processes[i].Kill();
}
Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
3

These commands are useful to control processes:

// check for processes
Process[] processes = Process.GetProcessesByName("nameOfExecutable");
foreach (Process proc in processes)
{   
   // do stuff
}

// start process (need path)
Process.Start("pathToExecutable");

// close gui process gently (if needed)
bool status = proc.CloseMainWindow();

// wait for process to close gently
bool status = proc.WaitForExit(killTimeMS);

// force close (kill) process
proc.Kill();
Avada Kedavra
  • 8,523
  • 5
  • 32
  • 48
1

If you implement a "no more than one" rule (which is well-documented, as you point out) and then implement the periodic crash-checker, that should be sufficient to ensure that one and only one copy is running.

In fact, the periodic process doesn't even have to check for a crash. It can just fire up an instance, which will immediately exit if another instance is already running, thanks to whatever "no more than one" mechanism you implement. This has the added benefit of avoiding a possible race-condition between detecting a dead process and starting a new one.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 1
    Your second point is very valid. But I'd have to think about the implications of that. Having a new instance start every five minutes and immediately stop when it detects another instance could have unforeseen consequences/overhead. – carlbenson Oct 07 '11 at 13:58
  • @CarlBenson: Don't forget that you are starting a new process every five minutes anyway. Also note my additional point about race-conditions. They might be very unlikely, but the general rule with concurrency is that if it *can* happen, it *will* happen. The usual way to prevent multiple running processes is for the one-and-only instance to lock a named resource for its entire lifespan, which makes race-conditions impossible. A program that runs briefly every few minutes can't do that. Also, there's nothing stopping you from implementing both a process-listing check and a mutex lock-out. – Marcelo Cantos Oct 07 '11 at 14:06
0

You have a few options. The first is checking for a running process using the Process class. I got this from a Microsoft site, but it looks like it works:

public bool IsProcessRunning(string name)
{
    //here we're going to get a list of all running processes on
    //the computer
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.StartsWith(name))
        {
            //process found so it's running so return true
            return true;
        }
    }

    //process not found, return false
    return false;
}

You could also use interprocess communications. This is something we do in house. We have a watcher application that sends a message to a service being monitored. If the service doesn't return an ACK in a timeout period, we attempt to restart it.

Josh
  • 2,955
  • 1
  • 19
  • 28
0

I suggest you to check if your application is in the list of running processes:
System.Diagnostics.Process.GetProcesses();

Otiel
  • 18,404
  • 16
  • 78
  • 126