【问题标题】:Is there any way to pause a Windows shutdown so that a forms.closing method can complete?有什么方法可以暂停 Windows 关闭,以便 forms.closure 方法可以完成?
【发布时间】:2017-02-22 23:04:38
【问题描述】:

当 Windows 开始关闭时,我试图将一些信息放入数据库中。在我的应用程序中,我正在处理 Form.Closing 事件。但是,Windows 将继续并关闭,我的方法没有时间完成。有没有办法暂停关机足够长的时间来处理关机?这是我目前正在使用的方法。

Private Sub frmMain_Closing(sender As Object, e As FormClosingEventArgs) Handles Me.Closing
        If e.CloseReason = CloseReason.WindowsShutDown Then
            _logger.Debug("Hit frmMain_Closing1")
            NewEvent(Events.SystemShutdownNormal)
            System.Threading.Thread.Sleep(10000)
            _logger.Debug("Hit frmMain_Closing 2")
        End If
    End Sub

每次我使用_logger.Debug("Hit...") 两次记录到日志文件时,只有第一次调用它时才会写入文件。我试过设置e.Cancel = True的方法,但是好像不行。

【问题讨论】:

  • 调用是刷新到文件还是只写入缓冲区?
  • @BenVoigt Tbh,我不确定。那部分不是我写的。我只知道我们使用它来记录文件。这是我唯一的调用,但我不确定它背后的机制。
  • Sleep 放在那里可能是个坏主意。
  • @AndrewMorton 是的,我已经删除了它。
  • 阻止关机的日子已经过去了,但它根本不起作用。您可以调用 ShutdownBlockReasonCreate(),以便在应用程序拒绝退出时在 Windows 显示的屏幕上显示一条消息。你必须说服用户你正在做一些非常重要的事情,这样他就不会点击忽略按钮。就像我一样,如果你花的时间超过 5 秒,他忽略它。

标签: vb.net windows winforms


【解决方案1】:

很抱歉造成这种错误信息。 简而言之,没有办法延迟或取消 Windows 关机。它将“很好地”点击所有进程以退出,然后通过并杀死任何没有的进程。 您可以延迟关闭,直到您的过程完成。为此,您需要使用ShutdownBlockReasonCreate()

您应该挂钩 WM_QUERYENDSESSION 消息,以便有机会做某事。您需要覆盖 WinProc,处理消息,然后调用基本 WinProc。看看https://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.sessionending(v=vs.110).aspx(向下滚动到备注。)

请记住,Windows 不会永远等待,但这会给您一些提前通知。希望足以让您有机会做任何您需要做的事情。优先处理重要的事情,希望它在进程被杀死之前完成。

一旦你连接了 WM_QUERYENDSESSION,你应该调用 ShutdownBlockReasonCreate() 阻止关闭,直到您的应用程序完成关闭。完成后,致电ShutdownBlockReasonDestroy()。有关详细信息,请参阅this MSDN article(向下滚动到“必须阻止关机的应用程序应使用新的关机原因 API”)。

PInvoke 声明可以是found herehere

【讨论】:

  • 您可以拦截该消息并提示用户取消关机,然后在您完成清理后以编程方式关机。像这样: Private Const WM_QUERYENDSESSION As System.Int32 = &H11 Private Const WM_CANCELMODE As System.Int32 = &H1F Protected Overrides Sub WndProc(ByRef ex As Message) If ex.Msg = WM_QUERYENDSESSION Then 'cancel message MsgBox("请取消关机" , MsgBoxStyle.Information) System.Diagnostics.Process.Start("cmd.exe", "/c shutdown /s") End If End Sub
  • @Neelix Reivsed 我的答案。 MS 创建了新的 API 来处理这个问题。
  • 是的,我今天要玩这个。我不得不更改注册表设置以允许程序暂停关机。我按照此处找到的方法进行操作:trishtech.com/2011/07/… 一旦我这样做了,我可以使用ShutdownBlockReasonCreate() 在 Frm_Load 上创建一个原因,并且我的程序能够运行,直到我调用 ShutdownBlockReasonDestroy() 方法。感谢您的帮助。
  • 不错!也感谢您对注册表设置发表评论。
猜你喜欢
  • 2020-10-02
  • 1970-01-01
  • 2022-09-23
  • 2023-03-12
  • 1970-01-01
  • 2015-01-28
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多