سؤال

IS there a way to catch all keyboard and mouse events from all applications running on Windows using .NET?

I've found some similar posts, the first being how to do this just for the application you are developing: VB Detect Idle time

As well as a post showing how to find how long the desktop has been idle: Check whether user is inactive

What I tried is below, basically using a timer in my main form that calls GetInactiveTime every 10 seconds and I record that time, then when CurrentInactiveTime < LastInactiveTime I raise an event. What I'm looking for is something that would be a little more real time and a little more precise.

<StructLayout(LayoutKind.Sequential)> _
Public Structure LASTINPUTINFO
    Public cbSize As UInteger
    Public dwTime As UInteger
End Structure

<DllImport("user32.dll")> _
Friend Shared Function GetLastInputInfo(ByRef plii As LASTINPUTINFO) As Boolean
End Function

Public Shared Function GetInactiveTime() As TimeSpan
    Dim info As LASTINPUTINFO = New LASTINPUTINFO()
    info.cbSize = CUInt(Marshal.SizeOf(info))

    If GetLastInputInfo(info) Then
        Return TimeSpan.FromMilliseconds(Environment.TickCount - info.dwTime)
    Else
        Return Nothing
    End If
End Function

Sub Main()
    inactiveTimer = New Timer()
    inactiveTimer.Interval = 10000
    inactiveTimer.Enabled = True
    inactiveTimer.Start()

    Dim tempTime As DateTime = Now
    lastInactiveTime = tempTime - tempTime
End Sub

Private Sub inactiveTimer_Tick(sender As Object, e As EventArgs) Handles inactiveTimer.Tick
    Dim currentInactiveTime As TimeSpan = GetInActiveTime()
    Dim tempLastInactiveTime As TimeSpan = lastInactiveTime

    lastInactiveTime = currentInactiveTime

    If currentInactiveTime < tempLastInactiveTime Then
         RaiseEvent SomeEvent
    End IF
End Sub

Also, I'm programming in a Windows/VB.NET environment.

Thanks for the help.

هل كانت مفيدة؟

المحلول

I've used this solution to the very same problem. It's code I found on the net, but I've adapted it to my needs.

You should be able to drop this into your code window and modify it as needed.

Public Structure LASTINPUTINFO
    Public cbSize As Int32
    Public dwTime As Int32

End Structure

Declare Function GetLastInputInfo Lib "User32.dll" (ByRef plii As LASTINPUTINFO) As Boolean

Private Sub IdleTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IdleTimer.Tick


    If ReportingEntireClass = False Then
        Dim LII As New LASTINPUTINFO, TicksSinceLastInput As Int32 = 0

        LII.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(LII)

        If GetLastInputInfo(LII) Then TicksSinceLastInput = (Environment.TickCount - LII.dwTime)

        If TicksSinceLastInput >= IdleSeconds Then
            If IdleClosing = False Then
                IdleClosing = True
                Idle.ShowDialog() 'this is a little 
                                  'form that warns about the app closing.
            End If
        End If
    End If


End Sub
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top