1

How do I check user is inactive? I have this:

class UserActivity : IMessageFilter
{
    private double afk_time = 0.1;//minutes
    private DateTime last_activity = DateTime.Now;
    public static bool inactive = false;

    private int WM_LBUTTONDOWN = 0x0201;
    private int WM_MBUTTONDOWN = 0x0207;
    private int WM_RBUTTONDOWN = 0x0204;
    private int WM_MOUSEWHEEL = 0x020A;
    private int WM_MOUSEMOVE = 0x0200;
    private int WM_KEYDOWN = 0x0100;

    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_LBUTTONDOWN || m.Msg == WM_MBUTTONDOWN || m.Msg == WM_RBUTTONDOWN || m.Msg == WM_MOUSEWHEEL || m.Msg == WM_MOUSEMOVE || m.Msg == WM_KEYDOWN)
        {
            this.last_activity = DateTime.Now;
            inactive = false;
        }

        if (DateTime.Now.AddMinutes(-afk_time) > last_activity)
            inactive = true;

        return false;
    }
}

But I must run it in Program.cs

Application.AddMessageFilter(new UserActivity());

How can I do that I can run the checking of user inactivity by my self. I'll check some checkbox and it will start checking.

And I want check global user activity - in all system not only in app.

I don't want use of cpu unnecessary. Or should I use another solution?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
sczdavos
  • 2,035
  • 11
  • 37
  • 71
  • Does this answer/help you? http://stackoverflow.com/questions/1421403/c-sharp-for-how-long-was-user-inactive – Chris Sinclair May 27 '12 at 17:56
  • I saw this thread, but I want check user inactivity in your link is Application_Idle event. I want know how long is user inactive (mouse and keyboard events). And I dont know if the solution what I use is correct and if it wont use a lot of CPU... – sczdavos May 27 '12 at 18:03

2 Answers2

8

I found this and it works perfect ! So if another one have problem with it here is solution:

    [StructLayout(LayoutKind.Sequential)]
    public struct LASTINPUTINFO
    {
        public uint cbSize;
        public uint dwTime;
    }

    [DllImport("user32.dll")]
    static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);


    public static TimeSpan? GetInactiveTime()
    {
        LASTINPUTINFO info = new LASTINPUTINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        if (GetLastInputInfo(ref info))
            return TimeSpan.FromMilliseconds(Environment.TickCount - info.dwTime);
        else
            return null;
    }
sczdavos
  • 2,035
  • 11
  • 37
  • 71
  • Note that Environment.TickCount returns signed int, which rolls over earlier than the unsigned int (DWORD) from WinApi GetTickCount. Maybe GetTickCount is safer to use. As LASTINPUTINFO.dwTime and GetTickCount are both DWORDs (unsigned ints). – Mike de Klerk Feb 20 '13 at 08:41
0

I have tried to build a class base on previous answer, I have test it and it work properly. It is async but i have not use async key. If someone finds some problem or amelioration so welcome.

public class User
{
    [StructLayout(LayoutKind.Sequential)]
    public struct LASTINPUTINFO
    {
        public uint cbSize;
        public uint dwTime;
    }

    [DllImport("user32.dll")]
    static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

    public static TimeSpan? GetInactiveTime()
    {
        LASTINPUTINFO info = new LASTINPUTINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        if (GetLastInputInfo(ref info))
            return TimeSpan.FromMilliseconds(Environment.TickCount - info.dwTime);
        else
            return null;
    }

    private TimeSpan? LastTime;
    private DispatcherTimer timer = new DispatcherTimer();
    public void RequestUserActivity()
    {
        LastTime = GetInactiveTime();
        timer.Interval = TimeSpan.FromMilliseconds(500);
        timer.Tick += timer_Tick;
        timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        TimeSpan? tmpTime = GetInactiveTime();
        if (LastTime.HasValue && tmpTime.HasValue && tmpTime < LastTime)
        {
            timer.Stop();
            UserAtivited(this, new EventArgs());
        }
        else if (!LastTime.HasValue || !tmpTime.HasValue)
        {
            timer.Stop();
            throw new Exception();
        }
    }

    public event EventHandler UserAtivited;
}

Now In your window create a new instance of User, register to UserActivated event and laugth RequestUserActivity(). I expert it will be helpfull.


Please, do not have regards on my poor english. I'm french speaker.

Max Winner
  • 23
  • 6