We help IT Professionals succeed at work.

Obtaining idle time via VB.NET.

182 Views
Last Modified: 2019-01-03
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?
Comment
Watch Question

DevAdminSystem Engineer | .NET Developer | Microsoft MVP | Technical Speaker
CERTIFIED EXPERT

Commented:
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
Ron MalmsteadInformation Services Manager
CERTIFIED EXPERT

Commented:
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
Sheldon LivingstonConsultant

Author

Commented:
I think the issue is with LASTINPUTINFO... it always returns zero while tick count is good.
DevAdminSystem Engineer | .NET Developer | Microsoft MVP | Technical Speaker
CERTIFIED EXPERT

Commented:
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)
Sheldon LivingstonConsultant

Author

Commented:
It appears that this cannot be done from a service... only an app.
DevAdminSystem Engineer | .NET Developer | Microsoft MVP | Technical Speaker
CERTIFIED EXPERT

Commented:
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
System Engineer | .NET Developer | Microsoft MVP | Technical Speaker
CERTIFIED EXPERT
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION
Sheldon LivingstonConsultant

Author

Commented:
Thank you Ermanno... I will be looking into this.