1

我写了一个简单的类来创建Microsoft.Win32.SystemEvents.PowerModeChanged事件的抽象,这是相关的代码:

Imports Microsoft.Win32

Public Class PowerStateMonitor

Private ReadOnly events As EventHandlerList

Public Custom Event SuspendInitiated As EventHandler(Of EventArgs)

    AddHandler(ByVal value As EventHandler(Of EventArgs))
        Me.events.AddHandler("SuspendInitiatedEvent", value)
    End AddHandler

    RemoveHandler(ByVal value As EventHandler(Of EventArgs))
        Me.events.RemoveHandler("SuspendInitiatedEvent", value)
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
        Dim handler As EventHandler(Of EventArgs) =
            DirectCast(Me.events("SuspendInitiatedEvent"), 
                       EventHandler(Of EventArgs))

        If (handler IsNot Nothing) Then
            handler.Invoke(sender, e)
        End If
    End RaiseEvent

End Event

Public Custom Event SuspendResumed As EventHandler(Of EventArgs)

    AddHandler(ByVal value As EventHandler(Of EventArgs))
        Me.events.AddHandler("SuspendResumedEvent", value)
    End AddHandler

    RemoveHandler(ByVal value As EventHandler(Of EventArgs))
        Me.events.RemoveHandler("SuspendResumedEvent", value)
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
        Dim handler As EventHandler(Of EventArgs) =
            DirectCast(Me.events("SuspendResumedEvent"), 
                       EventHandler(Of EventArgs))

        If (handler IsNot Nothing) Then
            handler.Invoke(sender, e)
        End If
    End RaiseEvent

End Event

Public Sub New()
    Me.events = New EventHandlerList
End Sub

Public Overridable Sub Start()
    AddHandler SystemEvents.PowerModeChanged, AddressOf Me.SystemEvents_PowerModeChanged
End Sub

Protected Overridable Sub OnSuspendInitiatedEvent(ByVal e As EventArgs)
    RaiseEvent SuspendInitiated(Me, e)
End Sub

Protected Overridable Sub OnSuspendResumedEvent(ByVal e As EventArgs)
    RaiseEvent SuspendResumed(Me, e)
End Sub

Private Sub SystemEvents_PowerModeChanged(ByVal sender As Object, 
                                          ByVal e As PowerModeChangedEventArgs)

    Select Case e.Mode

        Case PowerModes.Suspend
            Me.OnSuspendInitiatedEvent(Nothing)

        Case PowerModes.Resume
            Me.OnSuspendResumedEvent(Nothing)

    End Select

End Sub

End Class

问题是当我调用System.Windows.Forms.Application.SetSuspendState挂起或休眠系统时,SuspendInitiated我的类的事件没有引发。我尝试使用下面的代码通知 Suspend 状态,但没有任何反应,因为PowerModeChangedEventArgs.PowerModes属性的值永远不会发生,PowerModes.Suspend所以我的事件永远不会引发。

Friend WithEvents PowerStateMon As New PowerStateMonitor

Public Sub Suspend(Optional ByVal force As Boolean = False)

    Application.SetSuspendState(PowerState.Suspend, force:=force, disableWakeEvent:=True)

End Sub

Private Sub PowerStateMon_SuspendInitiated(ByVal sender As Object, ByVal e As EventArgs) _
Handles PowerStateMon.SuspendInitiated

    ' Application.Exit()
    Process.Start("CMD.exe", "/K Echo %TIME% The system is entering in Suspend state.")

End Sub

但是,当我恢复暂停状态时,我班级的其他事件SuspendResumed会正确通知我:

Private Sub PowerStateMon_SuspendResumed(ByVal sender As Object, ByVal e As EventArgs) _
Handles PowerStateMon.SuspendResumed

    Process.Start("CMD.exe", "/K Echo %TIME% The system resumed from Suspend state.")

End Sub

请注意 MSDN 文档说:

但是,一旦应用程序响应了挂起请求,它可能需要花费任何时间来清理资源并关闭活动进程。

我错过了什么?

更新

我注意到,如果我以正常行为挂起系统,我的意思是从 Windows 开始菜单,我会收到有关挂起的通知,但如果我使用该System.Windows.Forms.Application.SetSuspendState方法我不会收到通知,正如我所说,PowerModeChangedEventArgs.PowerModes属性的值永远不会是PowerModes.Suspend这个方式,为什么?

4

0 回答 0