C# Permante KeyDown Event Überwachung

Magic1416

Lieutenant
Registriert
Dez. 2003
Beiträge
513
Hi,

ich möchte eine Background Anwendung entwickeln, die überprüft, ob ein User idelt oder arbeitet. Wenn ein Benutzer für eine bestimmte Zeit X keine Aktionen an seinem Thinclient ausführt, sollen sämtliche offenen Terminalserver Sitzungen getrennt werden.
Die Arbeitsstation (ThinClient )kann nicht gesperrt werden. Daher der Bedarf.

Hierzu möchte ich das KeyDown und das MouseMove Event verwenden. Allerdings habe ich keine Ahnung, was ich machen muss, damit diese Ereignisse unabhängig vom Focus des Programms oder einem Form permanent überwacht werden.

Wie kann ich mir diese Ereignisse im Programm entsprechend abonieren ?

Danke Gruss Magic
 
Disconnect/Logoff nach einer bestimmten Idle-Zeit lässt sich Terminal-Server seitig einstellen.
 
Du könntest mit GetAsyncKeyState systemweit Tasten- und Mauseingaben abfangen.
Um deine Anforderung umzusetzen könntest du jedes mal einen Timer los laufen lassen der zählt, wie lang schon keine Angabe mehr erfolgt ist... Das ist aber nicht unbedingt die eleganteste Lösung, fiel mir nur gerade auf die Schnelle ein.
 
Also über Win32-Hooks kann man so Dinge zwar grundsätzlich machen, ob es in einer Terminal-Server-Umgebung funktioniert zweifle ich aber ein wenig an.
 
GreyhoundHH schrieb:
Disconnect/Logoff nach einer bestimmten Idle-Zeit lässt sich Terminal-Server seitig einstellen.
Aber das löst ja noch nicht das Problem, das er nicht weiß ob der User was macht oder nicht. Wenn du einfach nach einer bestimmten Zeit die Session trennst haste nen ganzen Haufen verärgerte User ^^

Könnte man das ganze nicht über einen Timer lösen, der beim Keypress oder beim MouseMove der ne variable auf nen Wert setzt und sonst nicht. Und dann könnte man ja den Timercount abfragen und dann nach einen bestimmten vorgabewert die Session trennen
 
Nur noch einmal zum Verständis. Das Tool, Dienst oder sonstwas soll auf einem unmananged ThinClient mit Windows Embedded laufen. Man kann dort die Arbeitsstation nicht sperren.
Das Tool soll, in welcher Form auch immer, dafür sorgen, dass nach einer bestimmten Zeit des Nichts-Tuns, die Session des Users getrennt und dessen WebPortal geschlossen wird, sodass es quasi einer Sperrung der Arbeitsstation gleich kommt.

Eine Terminalserver-seitige Lösung, die Sitzung zu trennen bringt imho nichts, solange das WebPortal offen bleibt.
Ergänzung ()

Meine erste Idee war / ist, das Tool mit einem Timer zu versehen, der nach Ablauf die Session trennt und die Webbrowser schließt. Die globalen Key und Mouse Events sollen den Timer zurücksetzen.
 
Timer bringt nix, denn Applikationen bekommen immer nur die Events für die sie zuständig sind, also MouseEvents wenn die Maus mit einem Fenster interagiert oder KeyboardEvents, wenn die Applikation den Focus hat. Eine Lösung um diese Events abzufangen wären sogenannte Global Hooks, aber da geht's schon sehr tief rein. Einfacher ist es in diesem Fall einfach die Idle-Time vom System auszulesen was über die WinAPI machbar ist (Stichwort pinvoke.net). Hab kurz mal gegooglet und ein Beispiel in C# gefunden... nachdem's über API-Call geht dürfte das auch ohne weiteres auf andere Sprachen übertragbar sein...

http://www.codeproject.com/KB/cs/GetIdleTimeWithCS.aspx

Nachtrag:
Timer braucht man dann natürlich schon, aber um die IdleTime auszulesen und nicht für irgendwelche Events... das is klar ;-)
 
Zuletzt bearbeitet: (Nachtrag)
@Vibrations
Das mit der Idle Time vom System ist ein sehr guter Hinweis gewesen, was die Sache ganz deutlich vereinfacht.

Hier der Quick und Dirty Code der App als Winform damit man auch was sehen kann:

Code:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;


namespace IdleTimeCheck
{
    internal struct LASTINPUTINFO
    {
        public uint cbSize;
        public uint dwTime;
    }
    
    public partial class Form1 : Form
    {
        [DllImport("User32.dll")]
        private static extern bool
            GetLastInputInfo(ref LASTINPUTINFO plii);
        
        System.Threading.Timer _t;
        uint _old, _new, _idlecount;

        LASTINPUTINFO _lastInPut;
                
        public Form1()
        {
            InitializeComponent();

            _lastInPut = new LASTINPUTINFO();
            _lastInPut.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(_lastInPut);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (_t == null)
            {
                draw_richtextbox("\nStarting Timer\n------------------------------\n");
                _t = new System.Threading.Timer(timer_callback, null, 500, 250);
            }
            else
            {
                _t.Dispose();
                _t = null;
                draw_richtextbox("\nStopping Timer\n------------------------------\n\n");
            }
        }

        private void timer_callback(object o)
        {
            GetLastInputInfo(ref _lastInPut);
            _new = _lastInPut.dwTime;

            if (_new == _old)
            {
                _idlecount++;
                 if (_idlecount < 40)
                    draw_richtextbox(String.Format("idle {0}\n",_idlecount));
                 else
                 {
                     draw_richtextbox("\nDisconnect Session; Terminate Explorer\nStopping Timer\n\n");
                     _idlecount = 0;
                     _t.Dispose();
                     _t = null;
                 }
            }
            else
            {
                _idlecount = 0;
            }

            _old = _new;
          
        }

        private delegate void stringhandler(string s); 
        private void draw_richtextbox(string s)
        {
            if (InvokeRequired)
            {
                stringhandler del = new stringhandler(draw_richtextbox);
                this.Invoke(del, s);
            }
            else
            {
                richTextBox1.AppendText(s);
                richTextBox1.ScrollToCaret();
            }
        }
    }
}
 
Zurück
Oben