Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# C#4.0 Console
Yes, I have a question. I have googled around, seen some suggestions on StackOverflow, but I just feel like there needs to be a nicer solution (plus, it needs to work on Windows 7).
 
I have a "Job Manager" that kicks off processes, controls how many are run at a time, their timeouts, kills them, etc, it basically steers a bunch of applications that it calls.
 
Anyways, I want to be able to kill all process (by process id would be fine, I manage them via id) when it is ungracefully shut down. Not errored out, but actually has the console close. People like to just close the console for some reason and now I have to account for it. I have tried this:
 
using System;
class Test {
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.ProcessExit += new EventHandler (OnProcessExit); 
        // Do something here
    }
 
    static void OnProcessExit (object sender, EventArgs e)
    {
        Console.WriteLine ("I'm out of here");
    }
}
 
Heck, I even have a KillAllProc app that just needs a string passed to it, just can't get it to run.
Posted 12-Feb-13 13:28pm
wizardzz104.9K
Comments
PIEBALDconsult at 12-Feb-13 18:47pm
   
I don't follow you. Are there 158 orphaned processes?
 
By "when it is ungracefully shut down" do you mean the bartender (the Job Manager)?
wizardzz at 12-Feb-13 19:15pm
   
Yeah, literally clicking X on the console window of the Job Manager.
Alan N at 12-Feb-13 21:08pm
   
Would it be possible to rewrite the Job Manager as a GUI app. You would then have more control over it's shutdown.
wizardzz at 12-Feb-13 21:50pm
   
I started going that route as a backup. Unfortunately, the Job Manager is often called via bat file that redirects the console output to a log. I could still make it work, but due to pressure from people running the application, have put that approach on hold.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

It turns out there is some Windows API trickery for this situation.
 
See the response by Willy Denoyette in http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/tree/browse_frm/thread/c72efe6c358eca9e/588a7bf4cfb4832[^]
 
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace DetectNaughtyUser {
  class Program {
    // http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/tree/browse_frm/thread/c72efe6c358eca9e/588a7bf4cfb4832

    public enum CtrlType {
      CTRL_C_EVENT = 0,
      CTRL_BREAK_EVENT = 1,
      CTRL_CLOSE_EVENT = 2,
      CTRL_LOGOFF_EVENT = 5,
      CTRL_SHUTDOWN_EVENT = 6
    }
 
    public delegate Boolean HandlerRoutine(CtrlType sig);
 
    [DllImport("kernel32.dll", EntryPoint = "SetConsoleCtrlHandler", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern Boolean SetConsoleCtrlHandler(
      HandlerRoutine handlerRoutine,
      [MarshalAs(UnmanagedType.Bool)] Boolean add);
 
    private static Boolean Handler(CtrlType sig) {
      Console.WriteLine("CtrlHandler {0}", sig);
      if (sig == CtrlType.CTRL_CLOSE_EVENT) {
        Console.WriteLine("Performing cleanup, please wait...");
        Thread.Sleep(2000);
      }
      return false;
    }
 
    static void Main() {
      SetConsoleCtrlHandler(Handler, true);
      Console.WriteLine("Click the Close button {X] or Press Enter to end...");
      Console.ReadLine();
    }
  }
}
 
It's advisable to make the "cleanup" quiet, as there is a warning on MSDN that console functions called from the handler may not work properly.
 
HandlerRoutine[^]
SetConsoleCtrlHandler[^]
 
Alan.
  Permalink  
Comments
wizardzz at 13-Feb-13 10:00am
   
I'm going to try this right now.
wizardzz at 13-Feb-13 10:20am
   
Hi Alan, I see that in your main() example code there is no += subscription to an event. However in the sample code after the jump, I see a line:
// Install handler
_handler += new EventHandler(Handler);
However, I don't know what _handler is supposed to be. As it is, your code doesn't work without the subscription part. I'll keep looking into it, thank you.
Alan N at 13-Feb-13 11:15am
   
My code didn't work, rats! Over here it does and I've just checked and can confirm that it a exact copy of my test code. Did you copy and paste it into a new solution or do a modified version?
 
The apparent event subscription in the original link is not required as the compiler does an implicit 'new' when assigning a method to a delegate type parameter.
SetConsoleCtrlHandler(Handler, true);
 
is equivalent to
SetConsoleCtrlHandler(new HandlerRoutine(Handler), true);
 
I'm on Windows XP and MSDN says nothing about problems in later versions.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

If I understand you correctly, you are trying to run some procedure after the user kills your process. Is that right?
 
In C++, I'd try executing the clean up procedure in the destructor of a global static object. But I don't know if that would even work, and there is no equivalent in C#.
 
I'm not sure that a properly design operating system should even allow that.
 
After all, if the user wants your process dead, he should be able to terminate it without letting it do anything else.
 
That said, the only way I could see to do it, would be to fire off a seperate watchdog process that monitors your main process and then does clean up if the main process is killed.
 
You'd have to implement some sort of interprocess communication. Maybe just a file that the main process writes a list of process id's to, and then deletes if it exits gracefully. Then if your watchdog process saw the main process was gone, it could check for the existence of the file and use the list in the file to kill all the other processes.
  Permalink  
Comments
Manfred R. Bihy at 12-Feb-13 19:09pm
   
That just about wraps it up nicely! 5+
wizardzz at 12-Feb-13 19:27pm
   
Thank you. I tried to 5 vote, but clicked 4, and dont seem to be able to change it to 5. =(

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 8,284
1 Sergey Alexandrovich Kryukov 7,327
2 DamithSL 5,614
3 Manas Bhardwaj 4,986
4 Maciej Los 4,920


Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 13 Feb 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100