如何模拟Windows关机进行调试?
当 Windows 关闭时,我的应用程序出现问题 - 我的应用程序无法正常退出,导致显示“结束任务”窗口。 如何使用调试器来查看发生了什么?
有没有办法将 Windows 关闭消息发送到我的应用程序,以便它认为 Windows 正在关闭,以便我可以准确地看到它的行为?
I have an issue with my application when Windows shuts down - my app isn't exiting nicely, resulting in the End Task window being displayed. How can I use the debugger to see what's going on?
Is there a way to send the Windows shutdown message(s) to my application so it thinks Windows is shutting down, so I can see exactly how it behaves?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我相信当 Windows 关闭时,它会向所有应用程序发送“WM_QueryEndSession”。 要模拟 Windows 关闭,您可以创建一个小应用程序,该应用程序只需将此消息发送到您的应用程序,然后看看会发生什么。 Windows 可能会发送比实际关闭应用程序更多的消息(例如 WM_CLOSE),但是每当您的应用程序收到“WM_QueryEndSession”消息时,就意味着您的应用程序即将从其下面拉出地毯。
I believe when Windows is shutting down it sends a "WM_QueryEndSession" to all applications. To simulate a Windows shutdown you could create a little application that just does a PostMessage with this message to your application and see what happens. Windows may send more messages than that to actually close your application (like WM_CLOSE), but whenever your application receives the "WM_QueryEndSession" message it means your application is about to have the rug pulled out from under it.
这可以使用 rmlogotest.exe 工具来完成。 请参阅以下链接:
https: //superuser.com/questions/959364/on-windows-how-can-i-graceously-ask-a-running-program-to-terminate#1154058
如果您使用的是 WPF,那么您可以处理附加事件:
您可以在其中设置
e.Cancel = true;
以中止应用程序关闭。我认为 rmlogotest.exe 使用 5 秒的超时,然后它会告诉你
徽标验证失败
。如果您在应用程序中放置某种消息框确认 - 您会遇到失败,对于最终用户来说,可能需要 5 秒以上的时间才能响应。
我想从 Windows 的角度来看,如果 5 秒过去了,它无论如何都会重新启动 - 如果最终用户还没有保存他的文档/工作 - 那么 Windows 可能希望将其复制到其他地方。
从我(作为应用程序开发人员)的角度来看 - 失败是可以接受的
LOGO Validation FAILED
,因为用户可以自行决定 - 他是否会在 5 秒后终止我的应用程序并丢失他的文档,或者他会保存文档并手动关闭我的应用程序。如果您需要广播
WM_QUERYENDSESSION
消息,则需要通过以下方式发送SendMessage
到当前进程中的所有窗口。 可以从这里找到启动示例代码:https://github.com/qakit/headless.git
但它只发送
WM_ENDSESSION
消息,您需要使用WM_QUERYENDSESSION
代替并添加给定进程的 Windows 枚举。相关链接:
This can be done using
rmlogotest.exe
tool. See following link:https://superuser.com/questions/959364/on-windows-how-can-i-gracefully-ask-a-running-program-to-terminate#1154058
If you're using WPF, then you can handle additional event:
where you can set
e.Cancel = true;
to be able to abort application closure.I think
rmlogotest.exe
uses timeout of 5 seconds and then it will tell you thatLOGO Validation FAILED
.If you put some sort of message box confirmation in your application - you get failure as for end-user it will take probably more than 5 seconds to respond.
I guess from windows perspective if 5 seconds passed by, it want to reboot anyway - and if end-user hasn't saved his document / work - then windows is expecting to copy it somewhere else maybe.
From my perspective (as application developer) - it's acceptable to have failing
LOGO Validation FAILED
, as user can decide on it's own - whether he will kill my application after 5 seconds and looses his document or he will save the document and closes my application manually.If you need to broadcast
WM_QUERYENDSESSION
message, then it needs to be sent viaSendMessage
to all windows in current process. Starting sample code can be found from here:https://github.com/qakit/headless.git
But it sends only
WM_ENDSESSION
message, you need to useWM_QUERYENDSESSION
instead and add windows enumeration of given process.Related links:
SendMessage 可用于将带有任何参数的窗口消息发送到窗口。
使用
LPARAM
=ENDSESSION_CLOSEAPP
发送消息WM_QUERYENDSESSION
。应用程序必须返回 1 (TRUE) 以指示它已准备好关闭并重新启动。
使用 LPARAM =
ENDSESSION_CLOSEAPP
发送消息WM_ENDSESSION
应用程序必须在指定的超时期限内关闭。
SendMessage can be used to send window messages with any parameters to a window.
Send the message
WM_QUERYENDSESSION
withLPARAM
=ENDSESSION_CLOSEAPP
.The application must return 1 (TRUE) to indicate it's prepared to shut down and restart.
Send the message
WM_ENDSESSION
with LPARAM =ENDSESSION_CLOSEAPP
The application must shut down within the specified timeout period.
您可以使用 SystemEvents.SessionEnding 事件,当用户注销或关闭时触发。 但使用时要小心,某些资源不能保证可用。 例如,我的应用程序需要在服务器关闭时访问服务器以让用户下班(时钟应用程序),但当此事件发生时,网卡有时已经被禁用。 由于您只是在进行清理,所以这应该可以正常工作。
You could use the SystemEvents.SessionEnding event, which is fired when a user logs off or shuts down. Be careful when using it though, some resources are not guaranteed to be available. For example, my application needed to hit a server when it was shutting down to clock a user out (a timeclock application), but the network card is sometimes already disabled when this event occurs. Since you're just doing cleanup, this should work fine.
Microsoft Windows 徽标测试工具中有一个名为 Restart Manager (rmtool.exe) 的工具,可用于向进程发送关闭和重新启动消息。 徽标测试工具可在此处下载:
http://download.microsoft.com/download/d/2/5/d2522ce4-a441-459d-8302-be8f3321823c/LogoToolsv1.0.msi
然后您可以模拟进程的关闭:
其中[PID] 是进程 ID。 根据 Vista 徽标认证测试用例文档,
There is a tool named Restart Manager (rmtool.exe) in the Microsoft's Logo Testing Tools for Windows, which can be used to send shutdown and restart messages to a process. Logo testing tools can be downloaded here:
http://download.microsoft.com/download/d/2/5/d2522ce4-a441-459d-8302-be8f3321823c/LogoToolsv1.0.msi
Then you can simulate shutdown for your process:
where [PID] is the process ID. According to the Vista Logo Certification Test Cases document,