2011-01-05 4 views
1

Ich habe ein Windows-App-Projekt, an dem sich Benutzer mit ihrer Benutzer-ID und ihren Passwörtern anmelden können. Ich möchte es so machen, dass, wenn sich ein Benutzer anmeldet, ich die Login-Zeit bekomme, und wenn der Benutzer die Anwendung 30 Minuten lang nicht benutzt, schickt die Anwendung den Benutzer wieder zum Login-Bildschirm. Wie kann ich das erreichen?Wie kann ich eine automatische Abmeldung innerhalb einer Windows Forms-Anwendung auslösen?

+1

Wie wäre es mit einem [Timer] (http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx)? –

+0

Ich stimme Cody Grey zu. Aber das wird hella nervig sein, von einem Benutzer Standpunkt ... – MPelletier

+0

Nein, ich denke, das ist nicht genug, nur muss es noch andere Dinge zu steuern Benutzeraktionen Tastatur und Maus Operationen. Weil ich so viele Formulare in meiner App habe. Form_Active Event und Timer Klasse ist dafür nicht ausreichend. –

Antwort

0

Dies ist die einfache Art und Weise hilft um dieses Problem zu lösen. Es funktioniert gut.

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

Warum deaktivieren Sie den Timer, wenn Aktivität vorhanden ist? Spezifisch, 'mTimer.Enabled = false;' innerhalb des 'if (active)' Blocks? –

+0

ist ein Beispiel nichts besonderes darauf. sein Neustart-Timer :), ich habe die Logik geändert. if (active) dann disable timer else timer start .. wenn ticker tick ereignis ausgelöst wird LoginDialog, wenn user erfolgreich einloggen kann ... looping so. –

+0

Keiner von denen machte * irgendeinen Sinn für mich. Es scheint, als ob Sie die 'Enabled' -Eigenschaft des Timers dort auf" true "setzen sollten, wenn Sie es starten (indem Sie seine' Start'-Methode aufrufen), aber wenn der Code für Sie funktioniert, was auch immer. –

9

Bearbeiten: Adam hat absolut Recht, ich habe die Frage missverstanden, also löschte ich meine ursprüngliche Antwort.

Um die Benutzeraktivität zu überwachen, können Sie eine benutzerdefinierte Form-basierte Klasse erstellen, von der Ihre Anwendungsformulare übernommen werden. Dort können Sie die MouseMove- und KeyDown-Ereignisse abonnieren (indem Sie die Eigenschaft KeyPreview auf true setzen), die bei jedem aktiven Benutzer ausgelöst werden. Sie können dann eine System.Threading.Timer mit der Fälligkeitszeit auf 30 Minuten erstellen und sie mit der Change() -Methode verschieben, sobald eine Benutzeraktivität erkannt wird.

Dies ist eine Beispielimplementierung: Das ObservedForm ist eher allgemein gehalten, so dass Sie das Muster leichter sehen können.

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

Jetzt können Sie auf die UserActivity Ereignis abonnieren, und machen Sie die Logiken Sie zum Beispiel wünschen:

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 
} 

Hoffnung, das hilft.

Bearbeiten # 2: einige Teile der Erklärung für Klarheit umformuliert und die Verwendung des FormClosing-Ereignisses zu FormClosed geändert.

+1

Eine Einschränkung besteht darin, dass der Timer die aktuelle Benutzeraktion ignoriert und annimmt, dass der Benutzer nur über ein festgelegtes Fenster verfügt, bevor ein Timeout auftritt. Timeouts treten normalerweise aufgrund von Benutzerinaktivität auf, die in Ihrem Beispiel nicht berücksichtigt wird. –

+0

@Adam: Du hast absolut recht, ich habe die Frage nicht sorgfältig genug gelesen. Siehe meinen bearbeiteten Post. – ShdNx

+0

Ich habe einen anderen Weg gefunden, um das zu lösen. Aber auch dein Weg sieht gut aus. Danke. –

1

Sie müssen eine Basisklasse für alle Ihre Formulare erstellen, die alle Benutzeraktivitäten abfangen und die letzte Aktivitätszeit speichern. Jedes Mal, wenn ein Benutzer auf etw klickt, müssten Sie das letzte Aktivitätsdatum überprüfen und entscheiden, ob es zu lange her ist oder nicht.

Im Moment habe ich keine Ahnung, wie abzufangen, aber ich bin mir ziemlich sicher, dass es möglich ist (vielleicht Fenster Nachrichten mit?)

0

1.st: Benutzer anmeldet, speichert den Zeitstempel irgendwo (für Beispiel dieser Unix-Zeitstempel '1294230230' sagt, es ist ungefähr 5. Januar 2011, 12:24)
int sess_creation_time = now();* können sagen, ‚now()‘ Funktion gibt aktuelle Unix-Zeitstempel

2.ten:, wenn der Benutzer eine Aktion auszuführen versucht, den Zeitstempel dieser Versuch fangen.
int temp_time = now();
Vergleichen Sie nun einfach diese Werte mit der gewünschten automatischen Abmeldegrenze.

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

Vergessen Sie nicht, das ist nicht in C/C++ oder C# geschrieben ist, aber die Logik bleibt gleich ;-)
Hope, das Ihnen ein wenig

Verwandte Themen