.net - Windows窗体处理程序在计算机唤醒时被忽略

标签 .net vb.net winforms event-handling wakeup

(范围:C#和VB.NET,尽管此处的代码在VB.NET中。)
我的WinForms应用程序在第一次挂起并恢复PC之前运行良好。恢复后,某些事件处理程序将被忽略。
日志记录机制记录了先暂停和先恢复。同样,第一次暂停并恢复后,VisualStudio中的断点在Sub PowerModeChanged()中停止。但是他们再也不会做。
Sub PowerModeChanged()再也不会被调用。
Sub FeedRawInput()再也不会被调用,并且击键进入标准WinForms处理程序,否则在我的应用程序中该处理程序将无效。
我对任何系统调整都不会感到困惑,这是相当标准的WinForms MDI应用程序。任何想法都可以杀死某些内部绑定,使事件在恢复后永不被调用吗?
如果我重新启动应用程序,一切立即都将再次正常运行...直到暂停恢复。

Sub Initialize() 'called from MainForm_Load()
    If AreAllSettingsMissing() Then PushAllDefaultSettings() 'needs database connections available
    AddHandler Microsoft.Win32.SystemEvents.PowerModeChanged, AddressOf PowerModeChanged

    _rawInput = New RawInputProcessor.RawFormsInput(My.Application.OpenForms(0),
                                                    RawInputProcessor.RawInputCaptureMode.Foreground)
    AddHandler _rawInput.KeyPressed, AddressOf FeedRawInput
End Sub

'my attempt to log suspend/resume and to rebuild USB scanner support
Sub PowerModeChanged(sender As Object, e As Microsoft.Win32.PowerModeChangedEventArgs)
    clsLogging.Log(String.Format("{0}:{1}:{2}", sender.ToString(), [Enum].GetName(GetType(Microsoft.Win32.PowerModes), e.Mode), _rawInput.ToString()))
    If e.Mode <> Microsoft.Win32.PowerModes.Resume Then Return
    'bring all down
    If _rawInput Is Nothing Then Return
    _rawInput.Dispose()
    _rawInput = Nothing
    RemoveHandler _rawInput.KeyPressed, AddressOf FeedRawInput 'problem 1 - called too late

    'restore all back
    _rawInput = New RawInputProcessor.RawFormsInput(My.Application.OpenForms(0),
                                                    RawInputProcessor.RawInputCaptureMode.Foreground)
    AddHandler _rawInput.KeyPressed, AddressOf FeedRawInput
End Sub


Sub FeedRawInput(sender As Object, e As RawInputProcessor.RawInputEventArgs)
    'push raw input key attributes into processing queue where 
    'each detected USB keyboard has its own async processing queue,
    'marshalling complete keystroke or scan back to main thread - standard stuff
End Sub

关于RawInput库,我已经移植了this one(C#-> VB)
这是this one的分支。目前,我不知道是否创建隐藏窗口(库用于捕获消息)在问题中起什么作用。 (但是它处理键盘,所以为什么还忽略电源事件?)当我在小型WPF项目中测试库时,它可以很好地保存下来。我尚未对独立库进行WinForms测试。
如果您有快速提示要在哪里检查,而不是漫长的拆卸所有工作,将应用程序分开以方便进行诊断等,请告诉我。
9小时后更新:

将标记为problem 1的行移到Dispose()之前,实现了轻微的改进。调试器不再奇怪地失去跟踪。
在删除多线程USB键盘解码器后,始终会调用处理程序PowerModeChanged()(不再忽略)。现在,它可以在挂起恢复后继续生存。

最佳答案

除了终止所有工作线程并在接收到Suspend事件时删除全局处理程序外,我没有找到解决方案(解决方法?)。计算机恢复后,在我的应用程序中接收到Resume事件时,我可以重新创建所有侦听器并重新添加全局处理程序。 (侦听器还不够,处理程序也需要“刷新”。)应用此方法后,它开始正常工作。



Sub PowerModeChanged(sender As Object, e As Microsoft.Win32.PowerModeChangedEventArgs)
    clsLogging.Log(String.Format("{0}:{1}:{2}",
                                 sender.ToString(),
                                 [Enum].GetName(GetType(Microsoft.Win32.PowerModes), e.Mode),
                                 Threading.Thread.CurrentThread.GetHashCode()))
    Select Case e.Mode
        Case Microsoft.Win32.PowerModes.Suspend
            My.Application.Scanners.Suspend()
                'inside: 1) send termination request to all threads
                '        2) clear USB keyboard map and any other references
                '        3) remove global raw keyboard event handler
                '        4) destroy instance of rawInput engine
        Case Microsoft.Win32.PowerModes.Resume
            My.Application.Scanners.Resume()
                'inside: undo (rebuild) steps 4, 3, 2, 1 seen in Suspend()
    End Select

    'debug printout: see list of all thread-powered device readers
    Dim logEntry As String = ""
    For Each key As IntPtr In My.Application.Scanners.Devices.Keys
        logEntry &= String.Format("{0} {1} ", key, My.Application.Scanners.Devices(key))
    Next
    clsLogging.Log(logEntry)
End Sub

关于.net - Windows窗体处理程序在计算机唤醒时被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28347604/

相关文章:

.net - 如何区分 WinForm 控件上的数据绑定(bind)和用户操作

.net - ASP.NET 配置文件版本控制?

c# - Log4Net在日志中打印 "ThreadID"和 "Thread Name"

vb.net - 项目将无法在 Debug模式下启动

vb.net - 将图标从主窗体继承到vb.net中的子窗体

c# - TreeView 文件夹结构有异常

c# - 从下一个控件触发 KeyUp 事件

.net - 我应该使用 Web API 还是 Web 方法?

c# - 我如何判断是否至少选择了一个 dataGridView 行 c#

.net - 仅当文件不存在时才使用PowerShell从SFTP服务器传输文件