By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,312 Members | 1,288 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,312 IT Pros & Developers. It's quick & easy.

killing a process from task manager does not fire console CTRL_CLOSE_EVENT

P: n/a
Hi,
I need to do some important cleanup before my console application
exists. I used the console ctrl event. This is working well and it
fires for all cases, including the CTRL_CLOSE_EVENT (if I close the
application from the X botton). But on
the contrary to what the MSDN indicates
(ms-help://MS.VSCC.2003/MS.MSDNQTR.2003OCT.1033/dllproc/base/handlerroutine.htm),
ending my process from the task manager did not fire the
CTRL_CLOSE_EVENT.
I also tried to use the Appdomain processexit, which didn't work for
any of the cases.
This is the code as I tried it:
public enum ConsoleEvent
{
CTRL_C = 0,
CTRL_BREAK,
CTRL_CLOSE,
CTRL_LOGOFF = 5,
CTRL_SHUTDOWN
}
public delegate void ControlEventHandler(ConsoleEvent
consoleEvent);
public event ControlEventHandler ControlEvent;
ControlEventHandler eventHandler;
public ConsoleCtrlEventsSetup()
{
// save this to a private var so the GC doesn't
collect it...
eventHandler = new
ControlEventHandler(Handler);
SetConsoleCtrlHandler(eventHandler, true);
}
~ConsoleCtrlEventsSetup()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
void Dispose(bool disposing)
{
if (disposing)
{
GC.SuppressFinalize(this);
}
if (eventHandler != null)
{
SetConsoleCtrlHandler(eventHandler,
false);
eventHandler = null;
}
}
private void Handler(ConsoleEvent consoleEvent)
{
if (ControlEvent != null)
ControlEvent(consoleEvent);
}
[DllImport("kernel32.dll")]
static extern bool
SetConsoleCtrlHandler(ControlEventHandler e, bool
add);
}
class CrashHandler
{
public static void
MyProcessExitHandler(ConsoleCtrlEventsSetup.Consol eEvent consoleEvent)
{
StopAllMotions();
}
public static void StopAllMotions ()
{
StreamWriter y =
File.AppendText(@"c:\temp\test.txt");
y.WriteLine("stopping all motions");
y.Flush();
y.Close();
}
}
public static void Main()
{
ConsoleCtrlEventsSetup cc = new
ConsoleCtrlEventsSetup();
cc.ControlEvent += new
ConsoleCtrlEventsSetup.ControlEventHandler(MyProce ssExitHandler);
Console.WriteLine("Press any key to exit");
}
Any ideas?
Thanks.

Dec 21 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
shiry,

Task Manager provides two ways of ending a process - from the *Applications*
tab clicking on the *End Task* button and from the *Processes* tab clicking
on the *End Process* button.

The *End Task* button is the one that MSDN referes to. The ctrl event should
fire in this case.

I doubt it that you'll get the event if one clicks on the *End Process*
button, though. It even warns you when you do that.
Ending a process with this button is abnormal termination.
--

Stoitcho Goutsev (100) [C# MVP]

"shiry" <sh****@gmail.com> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
Hi,
I need to do some important cleanup before my console application
exists. I used the console ctrl event. This is working well and it
fires for all cases, including the CTRL_CLOSE_EVENT (if I close the
application from the X botton). But on
the contrary to what the MSDN indicates
(ms-help://MS.VSCC.2003/MS.MSDNQTR.2003OCT.1033/dllproc/base/handlerroutine.htm),
ending my process from the task manager did not fire the
CTRL_CLOSE_EVENT.
I also tried to use the Appdomain processexit, which didn't work for
any of the cases.
This is the code as I tried it:
public enum ConsoleEvent
{
CTRL_C = 0,
CTRL_BREAK,
CTRL_CLOSE,
CTRL_LOGOFF = 5,
CTRL_SHUTDOWN
}
public delegate void ControlEventHandler(ConsoleEvent
consoleEvent);
public event ControlEventHandler ControlEvent;
ControlEventHandler eventHandler;
public ConsoleCtrlEventsSetup()
{
// save this to a private var so the GC doesn't
collect it...
eventHandler = new
ControlEventHandler(Handler);
SetConsoleCtrlHandler(eventHandler, true);
}
~ConsoleCtrlEventsSetup()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
void Dispose(bool disposing)
{
if (disposing)
{
GC.SuppressFinalize(this);
}
if (eventHandler != null)
{
SetConsoleCtrlHandler(eventHandler,
false);
eventHandler = null;
}
}
private void Handler(ConsoleEvent consoleEvent)
{
if (ControlEvent != null)
ControlEvent(consoleEvent);
}
[DllImport("kernel32.dll")]
static extern bool
SetConsoleCtrlHandler(ControlEventHandler e, bool
add);
}
class CrashHandler
{
public static void
MyProcessExitHandler(ConsoleCtrlEventsSetup.Consol eEvent consoleEvent)
{
StopAllMotions();
}
public static void StopAllMotions ()
{
StreamWriter y =
File.AppendText(@"c:\temp\test.txt");
y.WriteLine("stopping all motions");
y.Flush();
y.Close();
}
}
public static void Main()
{
ConsoleCtrlEventsSetup cc = new
ConsoleCtrlEventsSetup();
cc.ControlEvent += new
ConsoleCtrlEventsSetup.ControlEventHandler(MyProce ssExitHandler);
Console.WriteLine("Press any key to exit");
}
Any ideas?
Thanks.

Dec 21 '05 #2

P: n/a
Thanks,
So, that means that I cannot catch an Application crash in this manner?
What about AppDomain.CurrentDomain.ProcessExit function, can it help me
in case of a crash?
I read somewhere that the only way to catch a crash, in order to do
some cleanup, is to run a watcher application that uses the
System.Diagnostics.Process class, and get the return code of the
application. Is that correct? Is there any other way of doing this?

Dec 22 '05 #3

P: n/a

"shiry" <sh****@gmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Thanks,
So, that means that I cannot catch an Application crash in this manner?
What about AppDomain.CurrentDomain.ProcessExit function, can it help me
in case of a crash?
I read somewhere that the only way to catch a crash, in order to do
some cleanup, is to run a watcher application that uses the
System.Diagnostics.Process class, and get the return code of the
application. Is that correct? Is there any other way of doing this?


Killing a process is not an application crash isn't it?
When killing a process (from process explorer or whatever), the OS removes
the process cold, nothing is signaled because you are not supposed to kill a
process, unless it is no longer "functional", that is, it's no longer
runnable/responding, and because of this the OS sees no reason to signal the
process that it's going to be killed.
If you need to handle application crashes, you'll have to install a catch
handler.
Willy.
Dec 22 '05 #4

P: n/a
What do you mean by: "install a catch handler"?
(I'm pretty new to all this programming business, so excuse me for my
novice questions)

Dec 22 '05 #5

P: n/a
If you just need to do some cleanup, you can tie into the Process
Exited event. To do this you would have to have a watcher function like
you mentioned. All you would have to do is find your applications
Process object and use the following code.

Process currentProc = <your process, many ways to get this>;
currentProc.Exited += new EventHandler(processExited);

void processExited(object sender, EventArgs e)
{
//your clean up code goes here
}

Hope this helps

Dec 22 '05 #6

P: n/a
Just make sure you set process.EnableRaisingEvents to *true* otherwise the
exit event won't fire.
--

Stoitcho Goutsev (100) [C# MVP]

"Justin Creasy" <ju***********@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
If you just need to do some cleanup, you can tie into the Process
Exited event. To do this you would have to have a watcher function like
you mentioned. All you would have to do is find your applications
Process object and use the following code.

Process currentProc = <your process, many ways to get this>;
currentProc.Exited += new EventHandler(processExited);

void processExited(object sender, EventArgs e)
{
//your clean up code goes here
}

Hope this helps

Dec 22 '05 #7

P: n/a
Good call Stoitcho, I can't believe I forgot to mention that seeing as
I spent probably around 2 hours trying to find out why my event wasn't
firing and that was the answer. Thanks for catching that!

Dec 22 '05 #8

P: n/a

"Justin Creasy" <ju***********@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
If you just need to do some cleanup, you can tie into the Process
Exited event. To do this you would have to have a watcher function like
you mentioned. All you would have to do is find your applications
Process object and use the following code.

Process currentProc = <your process, many ways to get this>;
currentProc.Exited += new EventHandler(processExited);

void processExited(object sender, EventArgs e)
{
//your clean up code goes here
}

Hope this helps


This doesn't work for our own process (CurrentProcess), it only works for
process spawned from this process.
So there is nothing you can do in your handler other than accessing some of
the process properties like ExitCode, ExitTime ....
The reason for this is that the event is raised by the OS to the parent of
the process after the process has terminated.

Willy.
Dec 22 '05 #9

P: n/a

"shiry" <sh****@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
What do you mean by: "install a catch handler"?
(I'm pretty new to all this programming business, so excuse me for my
novice questions)


Something like this for a console program, will catch unhandled
exceptions...

public static void DoSomethingNasty()
{
int x=0,y=1;
Console.Write((y/x).ToString()); // this will throw a "devide by zero"
exception
}
static void Main(string[] args)
{

AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(GenericErrorHandler );
// Start a thread and do something bad...
Thread t = new Thread(new ThreadStart(DoSomethingNasty));
t.Start();
t.Join();
}
static void GenericErrorHandler(object sender,UnhandledExceptionEventArgs
e)
{
Console.WriteLine("Exiting...");
System.Environment.Exit(1); // terminate process and return error code
1 to parent process
}
Note that this doesn't catch process terminated by a "Kill" command!!!

Willy.
Dec 22 '05 #10

P: n/a
Thanks guys.
You've helped me a lot!

Dec 26 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.