I have a Windows App Project to which users can login with their userid and passwords. I want to make it so that when a user logs in, I will get the Login Time, and if the user doesn't use the application for 30 min, the application will send the user to the Login screen again. How can I achieve this?
-
1How about a [timer](http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx)? – Cody Gray - on strike Jan 05 '11 at 11:16
-
I agree with Cody Gray. But that's going to be hella annoying, from a user standpoint... – MPelletier Jan 05 '11 at 11:22
-
nope i think this isnt enough only there must be another things controlling user actions keyboard & mouse operations. Because I have got so many forms in my app.Form_Active event and timer class is insufficient for this. – İbrahim Akgün Jan 05 '11 at 11:31
4 Answers
Edit: Adam is absolutely right, I've misunderstood the question, so I deleted my original answer.
To monitor user activity, you could create a custom Form-based class from which your application forms will inherit. There you can subscribe to the MouseMove and KeyDown events (setting the KeyPreview property to true), either of which will be raised whenever the user is active. You can then create a System.Threading.Timer, with the due time set to 30 minutes, and postpone it using the Change() method whenever user activity is detected.
This is an example implementation below: the ObservedForm is written to be rather general, so that you can more easily see the pattern.
public class ObservedForm : Form
{
public event EventHandler UserActivity;
public ObservedForm()
{
KeyPreview = true;
FormClosed += ObservedForm_FormClosed;
MouseMove += ObservedForm_MouseMove;
KeyDown += ObservedForm_KeyDown;
}
protected virtual void OnUserActivity(EventArgs e)
{
var ua = UserActivity;
if(ua != null)
{
ua(this, e);
}
}
private void ObservedForm_MouseMove(object sender, MouseEventArgs e)
{
OnUserActivity();
}
private void ObservedForm_KeyDown(object sender, KeyEventArgs e)
{
OnUserActivity();
}
private void ObservedForm_FormClosed(object sender, FormClosedEventArgs e)
{
FormClosed -= ObservedForm_FormClosed;
MouseMove -= ObservedForm_MouseMove;
KeyDown -= ObservedForm_KeyDown;
}
}
Now you can subscribe to the UserActivity event, and do the logics you desire, for example:
private System.Threading.Timer timer = new Timer(_TimerTick, null, 1000 * 30 * 60, Timeout.Infinite);
private void _OnUserActivity(object sender, EventArgs e)
{
if(timer != null)
{
// postpone auto-logout by 30 minutes
timer.Change(1000 * 30 * 60, Timeout.Infinite);
}
}
private void _TimerTick(object state)
{
// the user has been inactive for 30 minutes; log him out
}
Hope this helps.
Edit #2: rephrased some parts of the explanation for clarity, and changed the use of the FormClosing event to FormClosed.

- 3,172
- 5
- 40
- 47
-
1One limitation is that the timer ignores current user action and assumes the user only has a set window before a time-out occurs. Time-outs usually occur due to user inactivity, which in your example is not catered for. – Adam Houldsworth Jan 05 '11 at 11:39
-
@Adam: you're absolutely right, I've not read the question carefully enough. See my edited post. – ShdNx Jan 05 '11 at 14:13
-
i have found another way to solve this.But also your way is looking good.Thank you. – İbrahim Akgün Jan 05 '11 at 21:58
-
I'd love to see a detailed explanation of how this works for someone who is new to custom events. – Span Mar 14 '12 at 02:18
-
This is the simple way to solve this problem. It's working well.
using System;
using System.Windows.Forms;
namespace WindowsApplication1 {
public partial class Form1 : Form, IMessageFilter {
private Timer mTimer;
private int mDialogCount;
public Form1() {
InitializeComponent();
mTimer = new Timer();
mTimer.Interval = 2000;
mTimer.Tick += LogoutUser;
mTimer.Enabled = true;
Application.AddMessageFilter(this);
}
public bool PreFilterMessage(ref Message m) {
// Monitor message for keyboard and mouse messages
bool active = m.Msg == 0x100 || m.Msg == 0x101; // WM_KEYDOWN/UP
active = active || m.Msg == 0xA0 || m.Msg == 0x200; // WM_(NC)MOUSEMOVE
active = active || m.Msg == 0x10; // WM_CLOSE, in case dialog closes
if (active) {
if (!mTimer.Enabled) label1.Text = "Wakeup";
mTimer.Enabled = false;
mTimer.Start();
}
return false;
}
private void LogoutUser(object sender, EventArgs e) {
// No activity, logout user
if (mDialogCount > 0) return;
mTimer.Enabled = false;
label1.Text = "Time'z up";
}
private void button1_Click(object sender, EventArgs e) {
mDialogCount += 1;
Form frm = new Form2();
frm.ShowDialog();
mDialogCount -= 1;
mTimer.Start();
}
}
}

- 2,336
- 5
- 31
- 40

- 1,527
- 11
- 37
- 63
-
Why do you disable the timer when there is activity? Specifically, `mTimer.Enabled = false;` inside of the `if (active)` block? – Cody Gray - on strike Jan 06 '11 at 05:56
-
its an example nothing special on it. its restarting timer :) , i have changed the logic. if (active) then disable timer else timer start.. when timer tick event raised calling LoginDialog if user can login succcessful... looping like this. – İbrahim Akgün Jan 06 '11 at 06:57
-
None of that made *any* sense to me. It seems like you should be setting the timer's `Enabled` property to "true" there if you are starting it (calling its `Start` method), but if the code works for you, whatever. – Cody Gray - on strike Jan 06 '11 at 13:19
-
if there is an activity I dont wanna start timer cuz there is LoginDialog calling operation in timer tick event so it must be enabled false, if there is no activity then timer must go on then call LoginDialog for Login Operation and wait for login. successfull.Yeah its working good.Ty Cody Gray – İbrahim Akgün Jan 06 '11 at 22:23
-
Hey, that's my code. Plagiarized from https://social.msdn.microsoft.com/Forums/en-US/815cfbf9-2303-4637-a7c2-d25ef5c1eeb3/auto-log-out-advice?forum=winforms – Hans Passant Dec 31 '19 at 08:49
You have to make a base class for all your Forms, that will intercept any user activity and store the last activity time. Each time user clicks sth you would have to check the last activity date and decide whether it was too long ago, or not.
At the moment I have no idea how to intercept, but I'm pretty sure it's possible (maybe using windows messages?)

- 4,721
- 1
- 25
- 20
1.st: User logs in, store the timestamp somewhere (for example this unix timestamp '1294230230' says it's aproximately 5th January 2011, 12:24)
int sess_creation_time = now(); *lets say 'now()' function returns current unix timestamp
2.nd: when user tries to perform any action, catch the timestamp of this attempt.
int temp_time = now();
Now, simply compare these values with your desired auto logout limit.
// compare here // a, temp_time - sess_creation_time => the difference, time of inactivity // 60*30 -> 60 seconds * 30 -> 30 minutes if( (temp_time - sess_creation_time) > (60*30) ) { // time of inactivity is higher than allowed, logout here logout(); } else { // session is still valid, do not forget to update its creation time sess_creation_time = now(); }
Do not forget, this is not written in C/C++ or C#, but the logic remains the same ;-)
Hope, this helps you a bit

- 22,476
- 5
- 61
- 65