【问题标题】:What might cause a Delphi program to 'prevent Windows shutdown'?什么可能导致 Delphi 程序“阻止 Windows 关机”?
【发布时间】:2014-03-06 14:12:55
【问题描述】:

我的一个 Delphi XE2 程序在运行和空闲时“防止 Windows 关机”。我的大多数应用程序都不是这种情况,我需要解决它。在 XP 上,Windows 静默无法关闭;在 Win7 上,对话框显示我的应用程序阻止关闭。

与这里的类似问题不同,该程序是单线程的,我没有使用托盘,并且我暂时断开了主窗体和具有它们的一个子窗体中的 OnCloseQuery 和 FormClose 事件。在正常使用中,程序会干净地关闭,并且不会在 Process Explorer 中留下任何痕迹。

我已经通过实验添加了 WM_QueryEndSession 和 WM_EndSession 处理程序,它们将日志消息写入 Windows 事件日志。在测试 Windows 关闭时,只有前者会触发,Wparam 和 Lparam 都为零。

如果您能提供任何关于可能导致此问题的原因或如何进一步调查的想法,我将不胜感激。我不愿意在不知道发生了什么的情况下尝试在 WM_QueryEndSession 上调用 Halt。

【问题讨论】:

  • 你可以实现WM_QueryEndSession并调用Application.Terminate
  • 为什么你的程序在窗口告诉它时不关闭?
  • @David:这正是我想要发现的!
  • 你能做一个SSCCE吗?
  • SSCCE 会很困难,因为 (a) 我的大多数应用程序都不会以这种方式运行,并且 (b) 在失败之前增加复杂性可能涉及许多繁琐的重启。

标签: delphi system-shutdown


【解决方案1】:

在失败的最终状态下,程序重新连接了 FormCloseQuery 方法,但在每个方法中,它现在都在检查“关闭”全局布尔值,如果设置了该值,则允许关闭。在主窗体上的 WM_QUERYENDSESSION 消息处理程序中,Shuttingdown 设置为 true。这适用于单一形式的应用程序。

这个问题是因为除了主窗体之外的 FormCloseQuery 处理程序都在主窗体上的 WM_QUERYENDSESSION 消息处理程序之前调用。在我进行的各种编辑和测试中,我错过了这个事实。

如果您的应用程序有任何具有 FormCloseQuery 处理程序的辅助表单,如果在随机时刻调用它,结果可能是“不关闭”(例如,在结束会话时,当表单可能尚未初始化时)那么你需要一个 WM_QUERYENDSESSION 消息处理程序在每个这样的形式。然后可以设置一个表单或局部变量,以使 FormCloseQuery 将 canclose 设置为 true。

【讨论】:

  • 我也遇到过类似的情况。辅助表单的 OnFormCloseQuery 阻止了整个应用程序被关闭。值得注意的是,此表单是在运行时创建的,但从未显示。所以这个缺陷并不明显,因为关闭查询将对每个现有的表单执行,而不仅仅是那些显示的表单。在我的例子中,一个未正确初始化的变量是罪魁祸首。
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 2011-04-03
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多