52

当 Windows 关闭时,我的应用程序出现问题 - 我的应用程序没有很好地退出,导致显示“结束任务”窗口。如何使用调试器查看发生了什么?

有没有办法将 Windows 关闭消息发送到我的应用程序,以便它认为 Windows 正在关闭,所以我可以确切地看到它的行为方式?

4

5 回答 5

65

在微软的 Windows 徽标测试工具中有一个名为 Restart Manager (rmtool.exe) 的工具,可用于向进程发送关闭和重启消息。标志测试工具可以在这里下载:

http://download.microsoft.com/download/d/2/5/d2522ce4-a441-459d-8302-be8f3321823c/LogoToolsv1.0.msi

然后您可以模拟您的进程的关闭:

rmtool.exe -p [PID] -S

其中 [PID] 是进程 ID。根据 Vista Logo 认证测试用例文档,

重新启动管理器关闭消息是:

一种。WM_QUERYENDSESSION with LPARAM = ENDSESSION_CLOSEAPP(0x1):GUI 应用程序必须立即响应 (TRUE) 以准备重新启动。

湾。WM_ENDSESSION with LPARAM = ENDSESSION_CLOSEAPP(0x1):应用程序必须在 5 秒内关闭(服务为 20 秒)。

C。CTRL_SHUTDOWN_EVENT:控制台应用程序必须立即关闭。

于 2010-04-20T08:58:56.583 回答
8

我相信当 Windows 关闭时,它会向所有应用程序发送“WM_QueryEndSession”。要模拟 Windows 关闭,您可以创建一个小应用程序,该应用程序只将此消息发送到您的应用程序的 PostMessage,然后查看会发生什么。Windows 可能会发送比实际关闭您的应用程序更多的消息(如 WM_CLOSE),但是每当您的应用程序收到“WM_QueryEndSession”消息时,这意味着您的应用程序即将从它下面拉出地毯。

于 2009-02-06T16:17:51.133 回答
1

SendMessage可用于向窗口发送带有任何参数的窗口消息。

对于调试和测试非常有用。

  1. WM_QUERYENDSESSION使用LPARAM=发送消息ENDSESSION_CLOSEAPP。应用程序必须返回 1 (TRUE) 以指示它已准备好关闭并重新启动。

  2. 发送WM_ENDSESSION带有 LPARAM =ENDSESSION_CLOSEAPP 应用程序必须在指定的超时期限内关闭的消息。

于 2018-03-08T06:33:27.647 回答
1

这可以使用rmlogotest.exe工具来完成。请参阅以下链接:

https://superuser.com/questions/959364/on-windows-how-can-i-gracefully-ask-a-running-program-to-terminate#1154058

如果您使用的是 WPF,那么您可以处理其他事件:

        Application.SessionEnding += Application_SessionEnding;

您可以在其中设置e.Cancel = true;能够中止应用程序关闭。

我认为rmlogotest.exe使用 5 秒的超时,然后它会告诉你 LOGO Validation FAILED

如果您在应用程序中放置某种消息框确认 - 您会失败,因为最终用户可能需要 5 秒以上的时间来响应。

我猜从 Windows 的角度来看,如果 5 秒过去了,它无论如何都想重新启动 - 如果最终用户没有保存他的文档/工作 - 那么 Windows 可能希望将它复制到其他地方。

从我的角度(作为应用程序开发人员) - 失败是可以接受的 LOGO Validation FAILED,因为用户可以自行决定 - 他是否会在 5 秒后杀死我的应用程序并丢失他的文档,或者他会保存文档并手动关闭我的应用程序。

如果您需要广播WM_QUERYENDSESSION消息,则需要将其发送 SendMessage到当前进程中的所有窗口。可以从这里找到起始示例代码:

https://github.com/qakit/headless.git

但它只发送WM_ENDSESSION消息,您需要改为使用WM_QUERYENDSESSION并添加给定进程的窗口枚举。

相关链接:

于 2020-12-21T11:32:51.693 回答
0

您可以使用SystemEvents.SessionEnding事件,该事件在用户注销或关闭时触发。使用时要小心,但不能保证某些资源可用。例如,我的应用程序在关闭时需要访问服务器以将用户打卡(时钟应用程序),但是当此事件发生时,网卡有时已经被禁用。由于您只是在进行清理,因此应该可以正常工作。

于 2009-02-06T16:30:15.443 回答