Wie kann man im Code bestimmen, wie lange die Maschine gesperrt ist?
Andere Ideen außerhalb von C # sind ebenfalls willkommen.
Ich mag die Windows-Service-Idee (und habe sie akzeptiert) aus Gründen der Einfachheit und Sauberkeit, aber leider glaube ich nicht, dass sie in diesem speziellen Fall für mich funktionieren wird. Ich wollte dies auf meiner Workstation bei der Arbeit und nicht zu Hause ausführen (oder zusätzlich zu Hause, nehme ich an), aber es ist dank des DoD ziemlich hart gesperrt. Das ist ein Teil des Grundes, warum ich meine eigenen rolle.
Ich werde es trotzdem aufschreiben und sehen, ob es funktioniert. Vielen Dank an alle!
Ich würde einen Windows-Dienst (einen Visual Studio 2005-Projekttyp) erstellen, der das OnSessionChange-Ereignis wie folgt behandelt:
Was und wie Sie die Aktivität zu diesem Zeitpunkt protokollieren, liegt bei Ihnen. Ein Windows-Dienst bietet jedoch schnellen und einfachen Zugriff auf Windows-Ereignisse wie Starten, Herunterfahren, Anmelden / Abmelden sowie Ereignisse zum Sperren und Entsperren.
quelle
Die folgende Lösung verwendet die Win32-API. OnSessionLock wird aufgerufen, wenn die Workstation gesperrt ist, und OnSessionUnlock wird aufgerufen, wenn sie entsperrt ist.
quelle
Ich weiß, dass dies eine alte Frage ist, aber ich habe eine Methode gefunden, um den Sperrstatus für eine bestimmte Sitzung zu erhalten.
Ich habe meine Antwort hier gefunden, aber sie war in C ++, also habe ich so viel wie möglich in C # übersetzt, um den Sperrstatus zu erhalten.
Also los geht's:
Hinweis: Der obige Code wurde aus einem viel größeren Projekt extrahiert. Wenn ich etwas verpasst habe, tut mir leid. Ich habe keine Zeit, den obigen Code zu testen, aber ich plane, in ein oder zwei Wochen wiederzukommen, um alles zu überprüfen. Ich habe es jetzt nur gepostet, weil ich nicht vergessen wollte, es zu tun.
quelle
if (session_info_ex.Level != 1)
- Wenn die Bedingung erfüllt ist, wird der Speicher nicht freigegeben. 2. Wenn session_info_ex.Level! = 1 ist, sollten Sie dies nicht tun:Marshal.PtrToStructure<WTSINFOEX>(ppBuffer);
da die Größe des zurückgegebenen Puffers von der Größe von WTSINFOEXUInt32 Reserved;
stattdessen sollten Sie die StrukturWTSINFOEX_LEVEL1
vollständig definieren . In diesem Fall führt der Compiler das korrekte Auffüllen (Ausrichten) von Feldern innerhalb der Struktur durch. 4. FunktionWTSFreeMemoryEx
wird hier missbraucht.WTSFreeMemory
muss stattdessen verwendet werden.WTSFreeMemoryEx
soll nachher Speicher freigebenWTSEnumerateSessionsEx
.CharSet = CharSet.Auto
muss in allen Attributen verwendet werden.Wenn Sie einen Windows-Dienst schreiben möchten, um diese Ereignisse zu "finden", hat topshelf (die Bibliothek / das Framework, die das Schreiben von Windows-Diensten erheblich vereinfacht) einen Haken.
und jetzt den Code, um den Topshelf-Service mit der Schnittstelle / dem Beton oben zu verbinden
Alles unten ist "typisches" Topshelf-Setup ... mit Ausnahme von 2 Zeilen, die ich als markiert habe
/ * DAS IST MAGISCHE LINIE * /
Dadurch wird die SessionChanged-Methode ausgelöst.
Ich habe dies mit Windows 10 x64 getestet. Ich habe meine Maschine gesperrt und entsperrt und das gewünschte Ergebnis erzielt.
Meine packages.config, um Hinweise zu Versionen zu geben:
quelle
x.EnableSessionChanged();
in Verbindung mit derServiceSessionChange
Schnittstellenimplementierung zu verwenden, wenn Sie eineServiceControl
implizite Serviceklasseninstanz implementiert haben und diese nicht erstellen. Wiex.Service<ServiceImpl>();
. Sie müssenServiceSessionChange
in derServiceImpl
Klasse implementieren :class ServiceImpl : ServiceControl, ServiceSessionChange
HINWEIS : Dies ist keine Antwort, sondern ein (Beitrag) zur Antwort von Timothy Carter , da ich aufgrund meines Rufs bisher keine Kommentare abgeben kann.
Nur für den Fall, dass jemand den Code aus Timothy Carters Antwort ausprobiert hat und ihn in einem Windows-Dienst nicht sofort zum Laufen gebracht hat, muss
true
im Konstruktor des Dienstes eine Eigenschaft festgelegt werden. Fügen Sie einfach die Zeile im Konstruktor hinzu:Und stellen Sie sicher, dass Sie diese Eigenschaft nicht festlegen, nachdem der Dienst gestartet wurde, da sonst eine
InvalidOperationException
ausgelöst wird.quelle
Unten finden Sie den 100% igen Arbeitscode, um festzustellen, ob der PC gesperrt ist oder nicht.
Bevor Sie dies verwenden, verwenden Sie den Namespace
System.Runtime.InteropServices
.quelle