Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB.NET: How to know time for which system is idle?

Tags:

.net

vb.net

I'm making an application in which I'm implementing auto-monitor turn off when system is idle, i.e. when user is not interacting with the system.

I found a link: http://www.codeproject.com/KB/system/SystemIdleTimerComponent.aspx

it does provides the componenent to know when system is idle. But when I include:

Public WM_SYSCOMMAND As Integer = &H112
Public SC_MONITORPOWER As Integer = &Hf170

<DllImport("user32.dll")> _
Private Shared Function SendMessage(hWnd As Integer, hMsg As Integer, wParam As Integer, lParam As Integer) As Integer
End Function

Private Sub button1_Click(sender As Object, e As System.EventArgs)
    SendMessage(Me.Handle.ToInt32(), WM_SYSCOMMAND, SC_MONITORPOWER, 2)
End Sub

It shows this error: Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.

like image 980
Viral Jain Avatar asked Nov 28 '25 00:11

Viral Jain


2 Answers

It shows this error: Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.

Don't access Form1 from another thread. Read up on the Invoke-pattern.

like image 58
Eddy Vluggen Avatar answered Nov 30 '25 15:11

Eddy Vluggen


I got LastInputInfo to work in my application by using a timer to retrieve it every 500ms, the code looks like this :

Private ATimer As DispatcherTimer

Public Sub New()
        ....

    ATimer = New DispatcherTimer
    AddHandler ATimer.Tick, AddressOf Me.ATimer_Tick
    ATimer.Interval = TimeSpan.FromMilliseconds(500)  'Checks for idle every 500ms
    ATimer.Start()
End Sub


Public Structure LASTINPUTINFO
    Public cbSize As Integer
    Public dwTime As Integer
End Structure

Private Declare Function GetTickCount Lib "kernel32" () As Long

Public Declare Function GetLastInputInfo Lib "User32.dll" _
                              (ByRef lii As LASTINPUTINFO) As Boolean

Private Sub ATimer_Tick(ByVal sender As Object, ByVal e As EventArgs)

    MyLastInputInfo = New LASTINPUTINFO
    MyLastInputInfo.cbSize = Runtime.InteropServices.Marshal.SizeOf(MyLastInputInfo)

   ' get last input info from Windows
    If GetLastInputInfo(MyLastInputInfo) Then     ' if we have an input info     
       ' compute idle time
       Dim sysIdleTime_ms As Integer = (GetTickCount() - MyLastInputInfo.dwTime)

    End if
       ... Now you have the idle time in ms, do whatever you want with it :=)

What MAY be a limitation of this way of doing things is that since times are stored in ticks within a 32bits integer, it 'only' works for 50 days after the last reboot of your computer (...). My guess though is that both the TickCount and the dwTime will wrap when the TickCount wraps, hence no issue, but could not test.

like image 39
GameAlchemist Avatar answered Nov 30 '25 14:11

GameAlchemist



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!