Link to home
Start Free TrialLog in
Avatar of Sheldon Livingston
Sheldon LivingstonFlag for United States of America

asked on

Obtaining idle time via VB.NET.

Happy new year all...

I am trying to get the system idle time via version 4 of the .NET framework using VB.NET.

Public Class idleTime
    Public Structure LASTINPUTINFO
        Public cbSize As UInteger
        Public dwTime As UInteger
    End Structure

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

    Public Function GetInactiveTime() As String ' Nullable(Of TimeSpan)
        Dim info As LASTINPUTINFO = New LASTINPUTINFO
        info.cbSize = CUInt(Marshal.SizeOf(info))

        If (GetLastInputInfo(info)) Then
            Return TimeSpan.FromMilliseconds(Environment.TickCount - info.dwTime).ToString '  
        Else
            Return "N/A" 'Nothing
        End If
    End Function
End Class

Open in new window

Through testing I see that info.dwTime always returns zero.

Thoughts?
Avatar of DevAdmin
DevAdmin
Flag of Italy image

Read this https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getlastinputinfo

If return 0 the function fails.

Try change the definitio of LASTINPUTINFO

Private Structure LASTINPUTINFO
      Dim cbSize As Int32
      Dim dwTime As Int32
End Structure
This link claims to have a working example.

https://stackoverflow.com/questions/8280799/vb-net-how-to-know-time-for-which-system-is-idle

Looks a lot like yours except this > 

Private Declare Function GetTickCount Lib "kernel32" () As Long
Avatar of Sheldon Livingston

ASKER

I think the issue is with LASTINPUTINFO... it always returns zero while tick count is good.
With these definition work for me:

Imports System.Runtime.InteropServices

    <StructLayout(LayoutKind.Sequential)> Structure LASTINPUTINFO
        <MarshalAs(UnmanagedType.U4)> Public cbSize As Integer
        <MarshalAs(UnmanagedType.U4)> Public dwTime As Integer
    End Structure

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

And I test idle time with this code:

        lastInputInf.cbSize = Marshal.SizeOf(lastInputInf)
        lastInputInf.dwTime = 0
        GetLastInputInfo(lastInputInf)
It appears that this cannot be done from a service... only an app.
Look at the help of the function

"This function is useful for input idle detection. However, GetLastInputInfo does not provide system-wide user input information across all running sessions. Rather, GetLastInputInfo provides session-specific user input information for only the session that invoked the function."

https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getlastinputinfo
ASKER CERTIFIED SOLUTION
Avatar of DevAdmin
DevAdmin
Flag of Italy image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you Ermanno... I will be looking into this.