"截距" Windows关闭并执行命令

时间:2014-09-20 17:21:06

标签: c++ windows multithreading winapi visual-c++

基本信息:

语言是c ++(visual c ++ 2013)。 我的程序是一个win32应用程序,多线程(3个线程),并且它的设计它作为关键进程运行(使用RtlSetProcessIsCritical,它完成工作)。我可以通过编程方式打开和关闭它(两个函数,一个将当前进程设置为关键,第二个将当前进程恢复为非关键)。

如果我只是点击开始 - >关闭窗口系统显然会崩溃bsod,如果你手动终止关键进程,你会得到同样的bsod。

我如何检测Windows关闭/重启的时间?所以我可以执行“转向非关键”功能,从而实现干净关闭。 :)

其中一个线程由一个每5或10秒运行一次的循环组成,在这里添加windows shutdown检测是唯一可行的选择。

我只尝试了一件事,WM_ENDSESSION如图所示http://msdn.microsoft.com/en-us/library/aa376889%28v=VS.85%29.aspx。但是它“无法”检测到os关闭,最终会出现一个bsod。

我会发现一些非常有用的例子或信息。如果需要额外的详细信息让我知道,我可以在几个小时内访问我的程序存储的计算机。 谢谢。

编辑:为什么downvote?我正在学习,想问一些我无法解决的问题。

编辑:你能提供一个例子,说明在我的循环中在何处/如何添加消息的实际检查?我不能克服这个问题,我已经在switch语句中使用了WM_QUERYENDSESSION案例..谢谢。

---------------编辑:

我不能让它工作,无论我尝试它不会工作.. 我的伪代码程序:

thread 1
 { 
  functionx();
  functiony();
 }


thread 2
 {
  functionz();
  functionf();
 }


thread 3
 {
   for (;;)
    {
      functiong();
      functionh();
    }
 }

int main()
 {
   thread 1;
   thread 2;
   thread 3;
 }

对于GetMessage部分,我使用了http://www.winprog.org/tutorial/window_click.html中的代码并重新调整以满足我的需求:

HWND hwnd;
MSG Msg;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_QUERYENDSESSION:
        function_to_turn_critical_process_OFF();
        return 0;
        break;

    case WM_ENDSESSION:
        function_to_turn_critical_process_OFF();
        return 0;
        break;
    }

    return 0;
}

消息循环:

while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
}
return Msg.wParam;
好吧,如果我在main()中插入消息循环作为第一个执行的问题我遇到问题编号1,GetMessage似乎把整个事情都放进去睡觉,所以我的程序甚至没有开始做他的东西。

如果我在main()中插入消息循环作为最后执行的事情(在线程3下)我遇到问题2,因为线程3永远不会结束(永远循环),消息循环可能永远不会启动。此外,线程3循环包含一点睡眠几秒钟,香港专业教育学院试图把get消息循环放在那里,但它无法捕捉它,我无法删除原始代码,无法更改循环或删除小睡眠功能。

如果我在线程3循环中插入消息循环,它就无法检测到WM_QUERYENDSESSION,并且我最终在Windows关闭时终止了BSOD,因此我的“关键关闭”功能没有被执行。

我该怎么办?谷歌没有帮助这个特殊的事情。我知道在一个简单的程序中,我应该将消息循环放在main中,它将在最后工作,但我在这里试图在我的代码中为这个消息循环找到一个位置。

任何帮助表示赞赏..

1 个答案:

答案 0 :(得分:3)

Windows会向应用程序发送两条消息:WM_QUERY_ENDSESSIONWM_ENDSESSION

你可以对他们做出反应,优雅地退出应用程序。

在您的情况下,WM_ENDSESSION可能为时已晚,无法让您更改应用优先级。

在WM_QUERY_ENDSESSION中,系统尚未关闭。因此,您可以调整设置,然后返回" 是的,当然!"。