【问题标题】:Windows 10 shutdown delay, VB.NETWindows 10 关机延迟,VB.NET
【发布时间】:2017-01-08 22:29:04
【问题描述】:

我想延迟关闭 Windows 10,以便我的应用可以完成一些必要的操作,例如保存数据...

以下是实现延迟的工作代码示例,但是 windows 在等待大约 1 分钟后取消关闭。

如何在不让 Windows 在一分钟后中止关机的情况下实现延迟? (我的应用可能需要 2 或 4 分钟才能完成)

Public Class Form1
Declare Function ShutdownBlockReasonCreate Lib "user32.dll" (ByVal hWnd As IntPtr, <Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal reason As String) As Boolean
Declare Function ShutdownBlockReasonDestroy Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean

Protected Overrides Sub WndProc(ByRef aMessage As Message)
    Const WM_QUERYENDSESSION As Integer = &H11
    Const WM_ENDSESSION As Integer = &H16

    If aMessage.Msg = WM_QUERYENDSESSION OrElse aMessage.Msg = WM_ENDSESSION Then
        ' Block shutdown
        ShutdownBlockReasonCreate(Me.Handle, "Testing 123...")

        ' Do work
        CleanUpAndSave()

        ' Continue with shutdown
        ShutdownBlockReasonDestroy(Me.Handle)

        Return
    End If

    MyBase.WndProc(aMessage)
End Sub

Private Sub CleanUpAndSave()
    Dim sw As New Stopwatch

    ' Pretend work for 3 minutes
    sw.Start()
    Do While sw.ElapsedMilliseconds < 180000
        Application.DoEvents()
    Loop
    sw.Stop()
End Sub

请提供工作代码(如果 Windows 完全可以的话)。

谢谢

【问题讨论】:

    标签: vb.net windows-10


    【解决方案1】:

    好吧,您可以做的一件事是让您的应用程序在完成必要的工作后触发关闭命令。

    更新:

    经过调查,发现带有ENDSESSION消息的WndProc方法被多次触发,导致CleanUpAndSave()也被再次执行。因此,除了关闭命令之外,您还需要添加一个布尔值来检查消息是否已经从系统发送到您的应用程序。

    以下代码经过测试,在 Windows 7windows 10 上都能正常运行:

    Private ShutdownDelayed As Boolean
    
    Protected Overrides Sub WndProc(ByRef aMessage As Message)
        Const WM_QUERYENDSESSION As Integer = &H11
        Const WM_ENDSESSION As Integer = &H16
    
        If aMessage.Msg = WM_QUERYENDSESSION OrElse aMessage.Msg = WM_ENDSESSION Then
            ' Check if the message was sent before and the shutdown command is delayed.
            If ShutdownDelayed Then Exit Sub
    
            ' Block shutdown
            ShutdownBlockReasonCreate(Me.Handle, "Testing 123...")
            ShutdownDelayed = True
    
            ' Do work
            CleanUpAndSave()
    
            ' Continue with shutdown
            ShutdownBlockReasonDestroy(Me.Handle)
    
            ' Do shutdown
            Dim p As New ProcessStartInfo("shutdown", "/s /t 0")
            p.CreateNoWindow = True
            p.UseShellExecute = False
            Process.Start(p)
    
            ' Exit the application to allow shutdown (For some reason 'ShutdownBlockReasonDestroy'
            '                                         doesn't really unblock the shutdown command).
            Application.Exit()
            Return
        End If
    
        MyBase.WndProc(aMessage)
    End Sub
    

    但是,我建议您不要暂停关闭命令并立即开始做一些工作而不提示用户确认消息特别是如果该工作需要几分钟时间.

    相反,您应该显示一个消息框,向用户说明应用程序需要在系统关闭之前执行一些工作,并让他们决定是否执行该工作或立即关闭。系统将通知用户您的应用程序正在阻止它关闭。如果他们关心,他们会单击“取消”并阅读您的消息。如果他们不在乎,他们仍然可以选择“强制关闭”无论您是否显示该消息

    希望有帮助:)

    【讨论】:

    • 如果用户在等待我的应用程序时改变主意并取消关机,或者用户只想注销,在这种情况下,PC 仍然会关闭,这会很烦人给用户。有什么想法吗?
    • @stacker,请阅读我回答的最后两段。正如我所说,您应该在不询问用户的情况下暂停关机(会令用户烦恼,并且在许多情况下,他们会强制关机 无论如何,当您的程序已经在处理工作时)。 您应该将该决定留给用户...
    • 在这种情况下,用户必须取消关机才能看到您的消息。如果他们选择Yes做工作/保存更改,那么你完成后不需要关机。如果他们选择No,那么您有多种选择: - 立即关机。 - 询问他们是否要关机/注销/重启? - 等等。我认为这是处理这种情况的理想方式。
    【解决方案2】:

    您不能将 Windows 关闭暂停超过几秒钟:https://blogs.msdn.microsoft.com/oldnewthing/20060216-06/?p=32263

    【讨论】:

    • 我不确定这篇文章有多准确,但我只是在 Windows 7 和 Windows 10 上测试了 OP 的代码。我设法将关机暂停“超过几秒钟”,这与文章不同索赔!在 Win7 上,它只是在一段时间后显示 “此程序正在阻止 Windows 关闭” 消息,而在 Win10 上,它只是在几乎一分钟后取消关机命令,如 OP 所述。还有其他资源可以备份该声明或清除此冲突吗?谢谢。
    • 嗯,经过一些研究,结果表明,自从 Windows Vista 以来不再允许的是 静默关闭取消,我想这就是本文所谈论的内容。然而,使用“用于主动注册关闭异议的新 APIShutdownBlockReasonCreate 仍然可以阻止关闭,这不能静默完成(系统将提供等待或关闭的选择)。更多信息on MSDNthis answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多