如何让自己的应用程序,控制台程序,windows 服务收到操作系统注销或者重启的消息

对于windows form的应用程序, 操作系统其实在注销或者关闭的时候,会发一个WM_QueryEndSession的消息给每一个窗体,每一个窗体有一个表决的机会,返回是否退出.这个跟form 的closing 时间一样. 一旦有一个程序返回false,那么这个注销动作就取消了.默认.net 写的windows 应用程序都是表决true,就是系统注销的时候,程序自动退出.


所以你要相应系统注销这个消息, 比如提醒用户要不要退出,或者作一些记录log的操作, 在.net 中只要挂一个事件处理到Microsoft.Win32.SystemEvents.SessionEnding 这个事件上面去.你可以做一些自定义的操作.比如:

private void HookSessionEnding()
{
Microsoft.Win32.SystemEvents.SessionEnding
+=
newMicrosoft.Win32.SessionEndingEventHandler(this.OnSessionEnding);
}

private void OnSessionEnding( object sender,
Microsoft.Win32.SessionEndingEventArgse)
{
//theusersessionisending
//MessageBox...
//取消系统关闭 e.cancel=true
}

当然也可以重载消息处理,自己处理WM_QueryEndSession 这个消息.

对于控制台应用程序,一般只能做到被动的接受,可以记录一下什么时候程序被关掉,是应为什么原因

实现方式其实就是调用系统api,有一些 SetConsole 打头的函数,用来实现 控制台应用程序的自定义,比如设置字体,颜色,窗体大小子类的. 2005 中其实对这些api做了一些包装. 这里主要是利用 SetConsoleCtrlHandler ,注册一个Handler

一下是vb.net 的一个框架

ModuleModule1 ModuleModule1
PublicDeclareFunctionSetConsoleCtrlHandler()FunctionSetConsoleCtrlHandlerLib"kernel32.dll"Alias"SetConsoleCtrlHandler"(ByValhandlerRoutineAsHandlerRoutine,ByValaddAsBoolean)AsBoolean
PublicDelegateSubHandlerRoutine()SubHandlerRoutine(ByValtypeAsInteger)

SubMain()SubMain()

SetConsoleCtrlHandler(
AddressOfMyHandle,True)
Console.ReadLine()

EndSub


PublicSubMyHandle()SubMyHandle(ByValtypeAsInteger)
'控制台收到那些消息
'0-CTLC
'1-CTL+Break
'2-CLOSE,可能是通过关闭close按钮也可能是直接关闭进程
'3-操作系统要注销
'4-系统要关机

'AddYourLog
EndSub


EndModule


3.对于windows 服务,api的话采取的是跟 console 类似的处理方式.只不过的他的状态切换更多
主要是调用一个 RegisterServiceCtrlHandler 的api

你可能感兴趣的:(.net,windows,Microsoft,vb,VB.NET)