14

I have a programm that runs another one (lets call the first app Stater and the second app - Worker).

I use

process.start();
process.waiForExit();
process.Close();

in Starter.

But if Starter is forced to close while waiting for Worker (for some extern reason) Worker will be still in processes, blocking files, eating memory etc.

So, I want to check if Worker is already running before I will try to start it. I've tried Process.GetProcessesByName("worker.exe") but no luck (even if I can see Worker in Task Manager).

I've seen some topics here about checking every process in memory for its modules, but still I already know the running file I hope to avoid such solution.

Any advices?

Pavel Oganesyan
  • 6,774
  • 4
  • 46
  • 84
  • Your title was a bit misleading. I thought you wanted to *hide* the true filename of the launching process for some obscure reason :) – Moo-Juice Mar 13 '12 at 10:02
  • Does `Starter` actually start `Worker`? If so, you know all the Process IDs (by means of `Process.Id`) of the workers. You can (much more reliable) handle them by ID then. – Christian.K Mar 13 '12 at 10:04
  • @Moo-Juice - that's exactly how I read it! The title desperately needs a comma between "C#" and "knowing". – adelphus Mar 13 '12 at 10:05
  • GetProcessesByName should work eg see http://stackoverflow.com/questions/3987414/c-sharp-pause-stop-system-diagnostics-process. Is it finding the running process or not? – kaj Mar 13 '12 at 10:06
  • Don't use the .exe. Just use `Process.GetProcessesByName("worker")` – Tung Mar 13 '12 at 10:06
  • 1
    *Don't* find the process by name. What happens if another unrelated application also launches a process called worker.exe? – adelphus Mar 13 '12 at 10:09
  • In general `GetProcessesByName()` does or should work, yes, but let's just hope there is no other, poor and lonely, unrelated process running that also has the name `Worker`... – Christian.K Mar 13 '12 at 10:10
  • To Christian - Can't use ID - worker can already be in memory because of previous situation. – Pavel Oganesyan Mar 13 '12 at 10:12
  • 2
    And let's face it, @Christian.K, with a name like `Worker`, it is going to be sad and lonely. I feel sorry for it already. – adelphus Mar 13 '12 at 10:14
  • Agree with last 2 comments, in my case "worker" is for example, real utility name is long and difficult. And it uses a lot of CPU and memory resources (some systems of diff equactions are solved in it), so no unneeded instances should be running. – Pavel Oganesyan Mar 13 '12 at 10:18
  • 1
    Put your process in a using block so that if the starter process exits abnormally it will still dispose of the worker process freeing any resources it may be consuming. – Despertar Mar 13 '12 at 10:22

5 Answers5

32

The reason you cannot find it is because you're using .exe. If the executable shows up as worker.exe in TaskManager, just call:

Process[] workers = Process.GetProcessesByName("worker")
foreach (Process worker in workers)
{
     worker.Kill();
     worker.WaitForExit();
     worker.Dispose();
}
Tung
  • 5,334
  • 1
  • 34
  • 41
  • 2
    I upvoted it (100% correct answer!), but the one with saving IDs to list is my favorite. – Pavel Oganesyan Mar 13 '12 at 10:22
  • No problem. Glad you solved your problem. When you get the process by ID, make sure that you verify the process name is "worker.exe". This will prevent you from killing another process that picked up the id you last saved – Tung Mar 13 '12 at 10:24
  • ```worker.WaitForExit()``` is freezing my application. Does any other alternative exist to know when the process exits? – NikSp Feb 03 '21 at 07:14
  • @NikSp, if you're writing a windows form application, your app will become unresponsive if you waitForExit in the UI thread (i.e main thread). Alternatively, you could periodically invoke Process.getProcessesByName after you issue the kill() until you don't see the process anymore, but this would be a hack. You should instead look into why your program hangs. – Tung Feb 03 '21 at 12:10
  • @Tung ty for the reply. I found a hack by using the ```WaitForExitAsync()``` in .NET 5.0 which unfreezes the UI while the file is used by the user. – NikSp Feb 03 '21 at 12:21
8

At the time of starting Worker process, save its ID in your application's configuration/setting file, in this way when you will launch your Starter process, it will first load that ID from settings file and will check if that process is currently running or not. If you want to immediately close Worker process, you can call process.Kill() on it.

Pavel Oganesyan
  • 6,774
  • 4
  • 46
  • 84
Software Engineer
  • 3,906
  • 1
  • 26
  • 35
  • 2
    Be careful: the ID might have been recycled (for a different process) by the time the Starter process restarts. You need additional checks to make sure it is actually (still) the process you think it is. – Christian.K Mar 13 '12 at 11:41
7

This is much easier...

System.Diagnostics.Process.Start("cmd.exe","/c taskkill /IM notepad.exe");

This code will close the Notepad (if it is running). Type the program name you want to close with it's extension (.exe).

Some applications cannot be stopped without forcing. Use /F after taskkill to force the action. If you want to close the process tree use /T after program name.

System.Diagnostics.Process.Start("cmd.exe","/c taskkill /F /IM notepad.exe /T");
Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80
2

When you call GetProcessesByName("worker") you don't specify exe extension as explained in MSDN
And if you wish to keep a global variable with the process object that you have started you could simply use the process.Kill();

Steve
  • 213,761
  • 22
  • 232
  • 286
2

If you only need to detect that "worker" is running, a technically much superior solution is have it lock a global mutex for the duration of its lifetime. Any process that knows the mutex name (which is under your control) can then see if the mutex is locked (if it is, worker is running).

However this is not easy to implement correctly as there are many little details you want to get just right; even then, there might be a race condition of "starter" and "worker" are actually launched simultaneously etc (of course this problem, and many others, also apply to all other solutions so it cannot be considered a drawback).

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806