Win32应用程序主要有两种类型:控制台应用程序(Console)和窗体程序(Winform),他们使用不同的方式处理应用程序退出。

要强制窗体程序(Winform)退出,你需要发送WM_CLOSE消息到主窗口句柄。.NET中可以使用Application.ApplicationExit或Form.Close。

在控制台应用程序,这点有所不同。控制台应用程序有点模仿DOS控制台应用程序,通常是在应用程序退出时,进程(命令)执行结束或Ctrl - C被按下。

在C#中,可以使用代理(委托)SetConsoleCtrlHandler 来实现。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
using System.Threading;
using System.Runtime.InteropServices;

// A simple class that exposes two static Win32 functions.
// One is a delegate type and the other is an enumerated type.
public class MyWin32
{
// Declare the SetConsoleCtrlHandler function
// as external and receiving a delegate.
[DllImport("Kernel32")]
public static extern Boolean SetConsoleCtrlHandler(HandlerRoutine Handler,
Boolean Add);

// A delegate type to be used as the handler routine
// for SetConsoleCtrlHandler.
public delegate Boolean HandlerRoutine(CtrlTypes CtrlType);

// An enumerated type for the control messages
// sent to the handler routine.
public enum CtrlTypes
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
}

public class MyApp
{
// A private static handler function in the MyApp class.
static Boolean Handler(MyWin32.CtrlTypes CtrlType)
{
String message = "This message should never be seen!";

// A switch to handle the event type.
switch (CtrlType)
{
case MyWin32.CtrlTypes.CTRL_C_EVENT:
message = "A CTRL_C_EVENT was raised by the user.";
break;
case MyWin32.CtrlTypes.CTRL_BREAK_EVENT:
message = "A CTRL_BREAK_EVENT was raised by the user.";
break;
case MyWin32.CtrlTypes.CTRL_CLOSE_EVENT:
message = "A CTRL_CLOSE_EVENT was raised by the user.";
break;
case MyWin32.CtrlTypes.CTRL_LOGOFF_EVENT:
message = "A CTRL_LOGOFF_EVENT was raised by the user.";
break;
case MyWin32.CtrlTypes.CTRL_SHUTDOWN_EVENT:
message = "A CTRL_SHUTDOWN_EVENT was raised by the user.";
break;
}

// Use interop to display a message for the type of event.
Console.WriteLine(message);

return true;
}

public static void Main()
{

// Use interop to set a console control handler.
MyWin32.HandlerRoutine hr = new MyWin32.HandlerRoutine(Handler);
MyWin32.SetConsoleCtrlHandler(hr, true);

// Give the user some time to raise a few events.
Console.WriteLine("Waiting 30 seconds for console ctrl events...");

// The object hr is not referred to again.
// The garbage collector can detect that the object has no
// more managed references and might clean it up here while
// the unmanaged SetConsoleCtrlHandler method is still using it.

// Force a garbage collection to demonstrate how the hr
// object will be handled.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

Thread.Sleep(30000);

// Display a message to the console when the unmanaged method
// has finished its work.
Console.WriteLine("Finished!");

// Call GC.KeepAlive(hr) at this point to maintain a reference to hr.
// This will prevent the garbage collector from collecting the
// object during the execution of the SetConsoleCtrlHandler method.
GC.KeepAlive(hr);
Console.Read();
}
}

参考:http://msdn.microsoft.com/en-us/library/s50zac30(vs.71).aspx