我有一个Windows应用程序项目,用户可以使用他们的用户ID和密码登录。我想这样做,以便当用户登录时,我将获得登录时间,如果用户未使用该应用程序30分钟,应用程序将再次将用户发送到登录屏幕。我怎样才能做到这一点?
答案 0 :(得分:11)
编辑:亚当是完全正确的,我误解了这个问题,所以我删除了原来的答案。
要监控用户活动,您可以创建一个基于自定义Form的类,您的应用程序表单将从该类继承。在那里,您可以订阅MouseMove和KeyDown事件(将KeyPreview属性设置为true),无论何时用户处于活动状态,都会引发其中任何一个。然后,您可以创建System.Threading.Timer,将截止时间设置为30分钟,并在检测到用户活动时使用Change()方法将其推迟。
这是一个下面的示例实现:ObservedForm编写得相当通用,以便您可以更轻松地查看模式。
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;
}
}
现在您可以订阅UserActivity事件,并执行您想要的逻辑,例如:
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
}
希望这有帮助。
编辑#2 :为了清晰起见,重新说明了部分解释,并将FormClosing事件的使用更改为FormClosed。
答案 1 :(得分:1)
您必须为所有表单创建一个基类,它将拦截任何用户活动并存储上次活动时间。每次用户点击时,您都必须检查最后一个活动日期,并确定它是否已经过了很长时间。
目前我不知道如何拦截,但我很确定它可能(可能使用Windows消息?)
答案 2 :(得分:1)
这是解决此问题的简单方法。它运作良好。
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();
}
}
}
答案 3 :(得分:0)
1.st:用户登录,将时间戳存储在某处(例如,此unix时间戳'1294230230'表示大约在2011年1月5日,12:24) int sess_creation_time = now(); *让我们说'now()'函数返回当前的unix时间戳
2.nd:当用户尝试执行任何操作时,请抓住此尝试的时间戳。
int temp_time = now();
现在,只需将这些值与您所需的自动注销限制进行比较即可。
// 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(); }
不要忘记,这不是用C / C ++或C#编写的,但逻辑保持不变;-)
希望,这对你有所帮助