如何在Windows窗体应用程序中触发自动注销?

我有一个Windows应用程序项目,用户可以使用他们的用户ID和密码登录。 我想这样做,以便当用户登录时,我将获得登录时间,如果用户没有使用该应用程序30分钟,应用程序将再次将用户发送到登录屏幕。 我怎样才能做到这一点?

编辑 :亚当绝对正确,我误解了这个问题,所以我删除了原来的答案。

要监视用户活动,您可以创建一个自定义的基于表单的类,您的应用程序表单将从该类inheritance。 在那里,您可以订阅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。

您必须为所有表单创建一个基类,它将拦截任何用户活动并存储上次活动时间。 每次用户点击时,您都必须检查最后一个活动日期,并确定它是否已经过了很久。

目前我不知道如何拦截,但我很确定它是可能的(可能使用Windows消息?)

这是解决此问题的简单方法。 它运作良好。

 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(); } } } 

1.st:用户登录,将时间戳存储在某处(例如,此unix时间戳’1294230230’表示大约在2011年1月5日,12:24)
int sess_creation_time = now(); *让我们说’now()’函数返回当前的unix时间戳

2.nd:当用户尝试执行任何操作时,请捕获此尝试的时间戳。
int temp_time = now();
现在,只需将这些值与您所需的自动注销限制进行比较即可。

 //比较一下
 // a,temp_time  -  sess_creation_time =>差异,不活动的时间
 // 60 * 30  - > 60秒* 30  - > 30分钟
 if((temp_time  -  sess_creation_time)>(60 * 30))
 {
   //不活动时间高于允许时间,请在此处注销
  登出();
 }
其他
 {
   //会话仍然有效,不要忘记更新其创建时间
   sess_creation_time = now();
 }

别忘了,这不是用C / C ++或C#编写的,但逻辑仍然相同;-)
希望,这对你有所帮助