0

ロードするメインフォームがあり、20分が経過したら、セキュリティ上の理由からログインフォームを開きたいです。適切なユーザーがソフトウェアを使用していることを確認したいので、タイマーの使用を検討し、タイマーに20分の間隔を設定しました。これは私のコードです:

private void timer1_Tick_1(object sender, EventArgs e)
{
    foreach (Form f in Application.OpenForms)
    {
        if (f.Name != "login2")
        {
            login2 lss = new login2();
            lss.ShowDialog(); 
        } 
    }
}

ここでの問題は、20分ごとにフォームが開くことです。つまり、ユーザーが何もしていない場合は、ログインフォームが次々と表示され、複数のログインフォームが表示されますが、これは望ましくありません。ループを使用しましたが、それでも正しく機能しません。何故かはわからない。

これとは別に、フォームが20分間アイドル状態の場合、ログインフォームを表示し、IDがアイドル状態ではない場合、ログインフォームを表示しないという機能を実装できますか?実装は簡単ですか?私はC#を初めて使用するのは初めてなので、複雑なことはしたくありません。

4

2 に答える 2

1

探しているのが、一定期間非アクティブになった後にユーザーをアプリケーションから効果的にログアウトする(または少なくともログアウトしているように見せること)ことである場合はGetLastInputInfo、要件を満たすためにp/invokeを実行できます。

タイマーティックイベント内で、GetLastInputInfoユーザー入力が最後に検出された時刻を返すために使用できます。これをEnvironment.TickCountから差し引くと、非アクティブな期間がわかります。ユーザーをログアウトするための基準を満たしている場合は、ログインフォームを表示できます。

[DllImport("User32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

[StructLayout(LayoutKind.Sequential)]
internal struct LASTINPUTINFO
{
    public uint cbSize;
    public uint dwTime;
}

private void timer1_Tick_1(object sender, EventArgs e)
{
    var lastInputInfo = new LASTINPUTINFO();
    lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);

    GetLastInputInfo(ref lastInputInfo);

    int inactivityThreshold = 20 * 60 * 1000;

    if ((Environment.TickCount - lastInputInfo.dwTime) > inactivityThreshold)
    {
        login2 lss = new login2();
        lss.ShowDialog(); 
    } 
}

フォームが複数回表示される問題を解決するには、ブール値を使用して現在ユーザーにログインしているかどうかを示し、ログインフォームを表示するかどうかの基準の一部として使用します。

于 2013-01-13T13:42:43.957 に答える
1

まず、タイマーをリセットする関数を追加します。

private void ResetTimer()
{
    timer1.Stop();
    timer1.Start();
}

呼び出されると、タイマーがリセットされます。

次に、複数のダイアログが開かないようにするには、同じインスタンスを使用します。そのログインフォームのインスタンスをクラスメンバーとして追加し、毎回新しいものを作成する代わりにそれを使用します。

login2 lss = new login2();
private void timer1_Tick(object sender, EventArgs e)
{
    if (!lss.Visible)
    {
        lss.ShowDialog();
        ResetTimer();
    }
}

ご覧のとおり、エラーを回避するために、ダイアログがまだ表示されていない場合にのみダイアログが呼び出されます。また、ユーザーがダイアログを終了した後、タイマーをリセットします。

最後に、「アイドル」時にのみカウントダウンするには、アクションがあるたびにタイマーをリセットする必要があります。単純なケースは、フォーム内のすべてのコントロールに対してマウスを移動してキーを押すことです。

this.Controls.Cast<Control>().ToList().ForEach(c =>
{
    c.MouseMove += (s1, e1) => ResetTimer();
    c.KeyPress += (s1, e1) => ResetTimer();
});

メインフォームのLoadイベント内にある場合、これによりすべてのコントロールにイベントハンドラーが割り当てられますが、ネストされたコントロールがある場合は、再帰を使用してすべてを取得する必要があります。

于 2013-01-13T13:59:33.017 に答える