5

I have a good old fashioned windows service (inheriting from System.ServiceProcess.ServiceBase), to which I added a component (implementing IComponent) by this.components.Add(new MyStuff());
However MyStuff's Disposable() doesn't run if I shut down the exe from Task Manager.

Possible suspects:

  • Nothing runs on "End Process". If so, how do I clean up after myself (e.g. kill started processes?)
  • For testing purposes I start my service with

    var service = new MyService();
    service.Run();
    Thread.Wait(Timeout.Infinite);

    instead of ServiceBase.Run(new []{new MyService()}); can that be the problem?

  • ServiceBase doesn't clean up automaticly. If so, what should I do?

Please help!

Additional info: I'm trying to shut down other exes I've started from my service using Process.Start(...), so if there's a way to make them auto-shutdown (child process?) that would be fine too.

TDaver
  • 7,164
  • 5
  • 47
  • 94
  • This looks like it might be relevant:http://stackoverflow.com/questions/3342941/kill-child-process-when-parent-process-is-killed – spender Oct 10 '11 at 14:22
  • 3
    If you can alter the code in both parent and child processes, it may be easier to have code in the child processes that detects the death of the parent and kills the child automatically. – Damien_The_Unbeliever Oct 10 '11 at 14:29
  • @Damien_The_Unbeliever: How do I detect it? Do I check if there are any processes with the same name as my parent? Isn't there something better? – TDaver Oct 10 '11 at 14:39
  • In addition to the other issues, note also that there is no guarantee that finalizers will run at process termination. If your finalizers take too long, the CLR will just give up. – Raymond Chen Oct 10 '11 at 14:45

3 Answers3

2

If you "pull the plug" there is nothing you can do at that moment. It is not considered a controlled shutdown. It is totally unexpected and nothing will give you the power to handle that from the inside of the process that is killed. It is not even considered a shutdown. To make that clear: You are not shutting down, you are killing it off! Its like ripping the power cord out of your computer and expecting it to shutdown gracefully. Wont work (though i had a tester write this very exact testcase for me a few years ago...)

Solve it:

  • Your child processes would need to "ping" the parent process. If it is not responding, you know that something is wrong and shutdown gracefully.

  • Or refer to the answer of ChrisBint (Service Controller). Get the service by name, start and stop it.

Find an example code here: http://www.csharp-examples.net/restart-windows-service/

  • Would the parent process respond if it died on an unhandled exception? Also, how to ping the parent process? I didn't find Process.GetCurrent().Parent or anything similiar – TDaver Oct 10 '11 at 14:41
  • Terminating from Task Manager is not the same as dying on an unhandled exception. Terminating from Task Manager is nuking from orbit, whereas the unhandled exception is something generated from within the process (so you have a chance of catching it). – Raymond Chen Oct 10 '11 at 14:44
  • If its dead, it wont reply (or it wouldnt be quite so dead, right?). You killed it via task manager, it wont respond anymore. It's gone. See my edited answer for some examples. –  Oct 10 '11 at 14:45
  • @RaymondChen You are right, i am strictly refering to the "Killing via Task Manager" scenario –  Oct 10 '11 at 14:57
2

My typical way of having children detect the death of a parent:

  • During parent startup, generate a nice, long, random name
  • Also during startup, obtain a named mutex with this name, and keep that held locked for the lifetime of the parent.
  • When starting a child process, pass the long random name as a parameter
  • In the children, dedicate a thread that attempts to obtain the same named mutex.
  • If the child ever obtains the mutex, the parent process must have died - so the child should exit also

By using a random name for the mutex, you ensure that a new hierarchy can be constructed even whilst the older parent/child hierarchy is in the process of being shut down.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • This sounds good. Will the mutex be released if the parent dies on an unhandled exception? – TDaver Oct 10 '11 at 14:46
  • Yes. From the [.Net Mutex class](http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx): "In the case of a system-wide mutex, an abandoned mutex might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager)." – Damien_The_Unbeliever Oct 10 '11 at 14:48
  • 1
    Much simpler is `Process.GetProcessById(parentId).WaitForExit()`. – Raymond Chen Oct 10 '11 at 15:47
1

Why are you stopping the service using Task Manager, you are basically killing it, not asking it to do something.

Put some code in the OnStop method to clean up and use Service Manager to stop/start the service.

ChrisBint
  • 12,773
  • 6
  • 40
  • 62