【问题标题】:"Intercept" Windows shut down and execute a command“拦截”Windows 关闭并执行命令
【发布时间】:2014-09-20 17:21:06
【问题描述】:

基本信息:

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

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

如何检测 Windows 何时关闭/重新启动?所以我可以执行“转向非关键”功能,从而彻底关闭。 :)

其中一个线程由每 5 或 10 秒运行一次的循环组成,在此处添加 Windows 关闭检测听起来是唯一可行的选择。

我只尝试了一件事,WM_ENDSESSION 如此处所示http://msdn.microsoft.com/en-us/library/aa376889%28v=VS.85%29.aspx。但它“未能”检测到操作系统关闭,并以蓝屏死机告终。

我会发现一些非常有用的示例或信息。如果需要其他详细信息,请告诉我,我将在几个小时内访问存储我的程序的计算机。 谢谢。

编辑:为什么要投反对票?我正在学习并想问一些我无法解决的问题。

编辑:您能否提供一个示例,说明在哪里/如何在我的循环中添加对消息的实际检查?我无法克服这个问题,我已经在 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 循环包含几秒钟的小睡眠,我试图将获取消息循环放在那里,但它未能捕获它,我无法删除原始代码,无法更改循环或删除小睡眠功能。

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

我能做什么?谷歌对这件事没有帮助。我知道在一个简单的程序中,我应该将消息循环放在 main 中,它会一直工作到最后,但我在这里发疯了,试图在我的代码中为这个消息循环找到一个位置。

任何帮助表示赞赏..

【问题讨论】:

  • 您的消息循环中是否收到任何消息?下面的 WM_QUERY_ENDSESSION 消息答案是正确的。您的程序 main 应该创建一个窗口,启动您的工作线程,然后执行消息处理循环。当您处理 WM_ENDSESSION 时,更改应用程序优先级,并可能发出信号让线程优雅地结束(SetEvent 或类似的东西)。

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


【解决方案1】:

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

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

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

在 WM_QUERY_ENDSESSION 中,系统尚未关闭。所以你可以调整你的设置,然后返回“是的,当然!”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多