Как запустить автоматический выход из системы в приложении Windows Forms? - PullRequest
2 голосов
/ 05 января 2011

У меня есть проект Windows App, в который пользователи могут войти со своими ИД пользователя и паролями.Я хочу сделать так, чтобы при входе пользователя в систему я получал время входа, а если пользователь не использует приложение в течение 30 минут, приложение снова отправит пользователя на экран входа в систему.Как мне этого добиться?

Ответы [ 4 ]

11 голосов
/ 05 января 2011

Редактировать : Адам абсолютно прав, я неправильно понял вопрос, поэтому я удалил свой первоначальный ответ.

Чтобы отслеживать активность пользователей, вы можете создать пользовательский класс 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
}

Надеюсь, это поможет.

Edit # 2 : перефразировал некоторые части объяснения для ясности и изменил использование события FormClosing на FormClosed.

1 голос
/ 06 января 2011

Это простой способ решить эту проблему. Работает хорошо.

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 голос
/ 05 января 2011

Вы должны создать базовый класс для всех ваших форм, который будет перехватывать любое действие пользователя и сохранять время последнего действия.Каждый раз, когда пользователь нажимает что-то, вам нужно будет проверить дату последней активности и решить, было ли это слишком давно или нет.

В настоящий момент я не знаю, как перехватить, но я почти уверен, что этовозможно (возможно, с использованием сообщений Windows?)

0 голосов
/ 05 января 2011

1.st: Пользователь входит в систему, где-то хранит метку времени (например, эта метка времени unix '1294230230' говорит, что приблизительно 5 января 2011 г., 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 #, но логика остается той же; -)
Надеюсь, это вам немного поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...