基本信息:
语言是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中,它将在最后工作,但我在这里试图在我的代码中为这个消息循环找到一个位置。
任何帮助表示赞赏..
答案 0 :(得分:3)
Windows会向应用程序发送两条消息:WM_QUERY_ENDSESSION和WM_ENDSESSION
你可以对他们做出反应,优雅地退出应用程序。
在您的情况下,WM_ENDSESSION可能为时已晚,无法让您更改应用优先级。
在WM_QUERY_ENDSESSION中,系统尚未关闭。因此,您可以调整设置,然后返回" 是的,当然!"。