Click here to Skip to main content
15,889,176 members
Articles / Programming Languages / C#
Article

Getting the user idle time with C#

Rate me:
Please Sign up or sign in to vote.
4.56/5 (38 votes)
10 Mar 20062 min read 256.4K   9.4K   69   42
Getting the user idle time using C# and the Windows API.

Sample Image

Introduction

System idle time is the time that has passed since the computer has received its last input from the user. It can be used to detect whether the user is idle or not. This feature is present in many instant messaging systems.

Visual Studio 2003 does not provide an explicit way to accomplish this, but I found an alternate method using C# code only.

Using the code

The implemented solution calls functions inside the user32.dll and kernel32.dll files.

To do this, it is necessary:

  1. To add a reference to the System.Runtime.InteropServices namespace.
  2. To know the name and definition of the function to be called.
  3. To create an extern function using C#.
  4. To make any additional structure to be used in the called functions.
C#
// Step 1
using System.Runtime.InteropServices;

// Steps 2 and 3
[DllImport("User32.dll")]
private static extern bool 
        GetLastInputInfo(ref LASTINPUTINFO plii);

//Step 4
internal struct LASTINPUTINFO 
{
    public uint cbSize;

    public uint dwTime;
}

When I was trying to make things works, I found an issue with the LASTINPUTINFO structure. I solved the problem by creating a C# struct with the same members as the original function. Note that you need to know the mapping between a Windows data type and the .NET Framework data types. The following table is very useful:

BOOLBoolean variable (should be TRUE or FALSE).
BOOLEANBoolean variable (should be TRUE or FALSE).
BYTEByte (8 bits).
CALLBACKCalling convention for callback functions.
CHAR8-bit Windows (ANSI) character.
COLORREFRed, green, blue (RGB) color value (32 bits).
CONSTVariable whose value is to remain constant during execution.
DWORD32-bit unsigned integer.
DWORD_PTRUnsigned long type for pointer precision. Use when casting a pointer to a long type to perform pointer arithmetic. (Also commonly used for general 32-bit parameters that have been extended to 64 bits in 64-bit Windows.)
INT32-bit signed integer.
INT_PTRSigned integral type for pointer precision. Use when casting a pointer to an integer to perform pointer arithmetic.
INT3232-bit signed integer.
INT6464-bit signed integer.
LONG32-bit signed integer.
LONG_PTRSigned long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic.
LONG3232-bit signed integer.
LONG6464-bit signed integer.
LONGLONG64-bit signed integer.
LPARAMMessage parameter.
LPBOOLPointer to a BOOL.
LPBYTEPointer to a BYTE.

When using a struct as a parameter, you have to initialize it before it is passed to the function:

LASTINPUTINFO lastInPut = new LASTINPUTINFO();
lastInPut.cbSize = (uint)
  System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);

The rest of the code does not contain any trick.

Using the code

The best method to use the code is compiling it in an DLL and using the functions asynchronously using a timer or threads.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Costa Rica Costa Rica
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionGetLastUserInput.GetIdleTickCount() Pin
rafaelly20067-Jan-18 22:05
rafaelly20067-Jan-18 22:05 
QuestionReset tick in an event Pin
Steve15f17-Mar-17 3:44
Steve15f17-Mar-17 3:44 
GeneralMy vote of 5 Pin
Halldorsson14-Aug-14 2:17
Halldorsson14-Aug-14 2:17 
SuggestionGetLastInputInfo additional info Pin
jorge_toriz16-Jun-14 7:39
jorge_toriz16-Jun-14 7:39 
BugBUG FOUND & FIXED: Environment.TickCount returns negative value in GetIdleTime() Windows 7 X64 Pin
jeffsdjfhj321-Jun-13 3:01
jeffsdjfhj321-Jun-13 3:01 
GeneralRe: BUG FOUND & FIXED: Environment.TickCount returns negative value in GetIdleTime() Windows 7 X64 Pin
sihirbazz10-Jun-14 8:58
sihirbazz10-Jun-14 8:58 
Hi, I don't know about VB.NET but can guess your work..First thank you for your warn.. I think this is not a bug, this is about System's Max Value of the returned numeric value..

As everyone know, in some situations .NET returns negative results when numerics get out of the range.

The 49 days are resultInMilisecs = 1000 for secs * 60 for mins * 60 for hours * 24 for the day * 49 = 4.233.600.000 milisecs and if we remember that an UInt MaxValue is = 4.294.967.296


with this little calculation and as you wrote (49.71 days or almost 49 days 17 hours 40 mins ) we can easily discover that 50 days is exactly overflow.

And for C# coders i wanna give a workaround idea for this situation which given as a bug by you:

There could be implement 2 numeric ( as one's project needs something like uint16 or int32 or int64) variables at the top of the code.

First variable (probably a const- constant variable in csharp-) must take responsive to a static tick count which represents a static time as a day or week or month

And the second variable is an incremental value which starts from zero.

so when the tick equals the first variable, our implementation sets the count of the last input time to zero and increment the second variable by 1..

with this little effort we can handle many max values of timeticks. As an example, if one decide the contant variable to set to one day of ticks, and second variable is simply Int16 Then we can handle 32767 days, not only <50 days Wink | ;-)

Thanks and regards.

modified 10-Jun-14 16:57pm.

GeneralRe: BUG FOUND & FIXED: Environment.TickCount returns negative value in GetIdleTime() Windows 7 X64 Pin
Dasiths17-May-15 14:26
Dasiths17-May-15 14:26 
GeneralMy vote of 4 Pin
Jorge Ali Urbina16-Mar-13 7:36
Jorge Ali Urbina16-Mar-13 7:36 
GeneralMy vote of 5 Pin
Supriya Srivastav11-Jan-12 21:50
Supriya Srivastav11-Jan-12 21:50 
GeneralMy vote of 5 Pin
andoniu1-Nov-11 21:53
andoniu1-Nov-11 21:53 
QuestionWorking in 64 bit Windows Pin
eduardo zola24-Jul-11 15:28
eduardo zola24-Jul-11 15:28 
GeneralMy vote of 5 Pin
That's Aragon21-Jul-11 2:47
That's Aragon21-Jul-11 2:47 
Generalthx Pin
binabic6-May-11 10:49
binabic6-May-11 10:49 
GeneralMy vote of 5 Pin
Gilberto Alexandre16-Feb-11 23:33
Gilberto Alexandre16-Feb-11 23:33 
QuestionIs it possible in Web forms? Pin
deja_anbu12-Feb-11 22:31
deja_anbu12-Feb-11 22:31 
GeneralBehave really bad on vista Pin
Sergejack27-Jan-10 5:17
Sergejack27-Jan-10 5:17 
GeneralRe: Behave really bad on vista Pin
av_tiuk3-Jun-10 6:33
av_tiuk3-Jun-10 6:33 
GeneralGetting the idle time of another system in network Pin
SHRIDHAR TL14-Oct-09 2:37
SHRIDHAR TL14-Oct-09 2:37 
GeneralRe: Getting the idle time of another system in network Pin
AyBeO17-Dec-09 18:56
AyBeO17-Dec-09 18:56 
GeneralPretty slick Pin
Mythos724-Aug-09 9:29
Mythos724-Aug-09 9:29 
GeneralVirtual machine Issues Pin
snorkie16-Apr-09 12:07
professionalsnorkie16-Apr-09 12:07 
AnswerThis little piece of code saved me this morning Pin
German Sosa11-Apr-09 4:35
German Sosa11-Apr-09 4:35 
GeneralFantastic Pin
z00z07-Oct-08 7:04
z00z07-Oct-08 7:04 
Generalwell done Pin
alexandru robert, agrapine6-Jun-08 23:16
alexandru robert, agrapine6-Jun-08 23:16 
Generalabsolutely great! Pin
Luis Miguel Silva16-Feb-08 12:46
Luis Miguel Silva16-Feb-08 12:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.