對於windows form的應用程式, 作業系統其實在登出或者關閉的時候,會發一個WM_QueryEndSession的訊息給每一個表單,每一個表單有一個表決的機會,返回是否退出.這個跟form 的closing 時間一樣. 一旦有一個程式返回false,那麼這個登出動作就取消了.預設.net 寫的windows 應用程式都是表決true,就是系統登出的時候,程式自動結束.
所以你要相應系統登出這個訊息, 比如提醒使用者要不要退出,或者作一些記錄log的操作, 在.net 中只要掛一個事件處理到Microsoft.Win32.SystemEvents.SessionEnding 這個事件上面去.你可以做一些自訂的操作.比如:
private void HookSessionEnding()
{
Microsoft.Win32.SystemEvents.SessionEnding +=
new Microsoft.Win32.SessionEndingEventHandler(this.OnSessionEnding);
}
private void OnSessionEnding( object sender,
Microsoft.Win32.SessionEndingEventArgs e )
{
// the user session is ending
//MessageBox...
//取消系統關閉 e.cancel=true
}
當然也可以重載訊息處理,自己處理WM_QueryEndSession 這個訊息.
對於控制台應用程式,一般只能做到被動的接受,可以記錄一下什麼時候程式被關掉,是應為什麼原因
實現方式其實就是調用系統api,有一些 SetConsole 打頭的函數,用來實現 控制台應用程式的自訂,比如設定字型,顏色,表單大小子類的. 2005 中其實對這些api做了一些封裝. 這裡主要是利用 SetConsoleCtrlHandler ,註冊一個Handler
一下是vb.net 的一個架構
Module Module1Module Module1
Public Declare Function SetConsoleCtrlHandler()Function SetConsoleCtrlHandler Lib "kernel32.dll" Alias "SetConsoleCtrlHandler" (ByVal handlerRoutine As HandlerRoutine, ByVal add As Boolean) As Boolean
Public Delegate Sub HandlerRoutine()Sub HandlerRoutine(ByVal type As Integer)
Sub Main()Sub Main()
SetConsoleCtrlHandler(AddressOf MyHandle, True)
Console.ReadLine()
End Sub
Public Sub MyHandle()Sub MyHandle(ByVal type As Integer)
' 控制台收到那些訊息
' 0- CTL C
' 1- CTL + Break
' 2- CLOSE,可能是通過關閉close按鈕也可能是直接關閉進程
' 3- 作業系統要登出
' 4- 系統要關機
'Add Your Log
End Sub
End Module
3.對於windows 服務,api的話採取的是跟 console 類似的處理方式.只不過的他的狀態切換更多
主要是調用一個 RegisterServiceCtrlHandler 的api