Obtaining idle time via VB.NET.

Sheldon Livingston
Sheldon Livingston used Ask the Experts™
on
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

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
DevAdminSystem Engineer | .NET Developer | Microsoft MVP | Technical Speaker

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

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.
OWASP Proactive Controls

Learn the most important control and control categories that every architect and developer should include in their projects.

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

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

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
Commented:
For obtain the idle time in a service you must monitoring global events look at this article:
https://www.codeproject.com/Articles/9104/How-to-check-for-user-inactivity-with-and-without
Sheldon LivingstonConsultant

Author

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

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial