Jak można określić w kodzie, jak długo maszyna jest zablokowana?
Inne pomysły poza C # są również mile widziane.
Podoba mi się pomysł na obsługę okien (i zaakceptowałem go) ze względu na prostotę i czystość, ale niestety nie sądzę, że zadziała w tym konkretnym przypadku. Chciałem uruchomić to na mojej stacji roboczej w pracy, a nie w domu (lub jak przypuszczam oprócz domu), ale jest to dość trudne dzięki uprzejmości DoD. Właściwie to jeden z powodów, dla których skręcam własne.
I tak to spiszę i zobaczę, czy zadziała. Dziękuję wszystkim!
Utworzyłbym usługę Windows (typ projektu Visual Studio 2005), która obsługuje zdarzenie OnSessionChange, jak pokazano poniżej:
To, co i jak zarejestrujesz aktywność w tym momencie, zależy od Ciebie, ale usługa Windows zapewnia szybki i łatwy dostęp do zdarzeń systemu Windows, takich jak uruchamianie, zamykanie, logowanie / wylogowywanie, a także zdarzenia blokowania i odblokowywania.
źródło
Poniższe rozwiązanie wykorzystuje interfejs API Win32. OnSessionLock jest wywoływana, gdy stacja robocza jest zablokowana, a OnSessionUnlock jest wywoływana, gdy jest odblokowana.
źródło
Wiem, że to stare pytanie, ale znalazłem metodę uzyskania stanu blokady dla danej sesji.
Znalazłem moją odpowiedź tutaj, ale była w C ++, więc przetłumaczyłem jak najwięcej na C #, aby uzyskać stan blokady.
Więc oto idzie:
Uwaga: powyższy kod został wyodrębniony ze znacznie większego projektu, więc jeśli trochę przegapiłem. Nie miałem czasu na przetestowanie powyższego kodu, ale planuję wrócić za tydzień lub dwa, aby wszystko sprawdzić. Opublikowałem to tylko teraz, ponieważ nie chciałem o tym zapomnieć.
źródło
if (session_info_ex.Level != 1)
- jeśli warunek jest prawdziwy, pamięć nie zostanie zwolniona. 2. jeśli session_info_ex.Level! = 1 nie powinieneś tego robić:Marshal.PtrToStructure<WTSINFOEX>(ppBuffer);
ponieważ rozmiar zwracanego bufora może różnić się od rozmiaru WTSINFOEXUInt32 Reserved;
zamiast tego należyWTSINFOEX_LEVEL1
całkowicie zdefiniować strukturę . W tym przypadku kompilator wykona poprawne wypełnienie (wyrównanie) pól wewnątrz struktury. 4. FunkcjaWTSFreeMemoryEx
jest tu niewłaściwie używana.WTSFreeMemory
należy użyć zamiast tego.WTSFreeMemoryEx
ma zwolnić pamięć poWTSEnumerateSessionsEx
.CharSet = CharSet.Auto
należy używać we wszystkich atrybutach.Jeśli jesteś zainteresowany napisaniem usługi Windows, która "wyszukuje" te zdarzenia, topshelf (biblioteka / framework, który znacznie ułatwia pisanie usług Windows) ma haczyk.
a teraz kod do połączenia usługi górnej półki z interfejsem / betonem powyżej
Wszystko poniżej jest "typową" konfiguracją górnej półki… z wyjątkiem 2 linii, które oznaczyłem jako
/ * TO JEST MAGICZNA LINIA * /
To one powodują uruchomienie metody SessionChanged.
Przetestowałem to w systemie Windows 10 x64. Zablokowałem i odblokowałem moją maszynę i uzyskałem pożądany rezultat.
My packages.config, aby zapewnić wskazówki dotyczące wersji:
źródło
x.EnableSessionChanged();
w połączeniu zServiceSessionChange
implementacją interfejsu, jeśli zaimplementowanoServiceControl
i nie utworzono implicity instancji klasy usług. Lubięx.Service<ServiceImpl>();
. Trzeba zaimplementowaćServiceSessionChange
wServiceImpl
klasie:class ServiceImpl : ServiceControl, ServiceSessionChange
UWAGA : To nie jest odpowiedź, ale (wkład) do odpowiedzi Timothy'ego Cartera , ponieważ moja reputacja nie pozwala mi do tej pory komentować.
Na wypadek gdyby ktoś wypróbował kod z odpowiedzi Timothy'ego Cartera i nie udało mu się go od razu uruchomić w usłudze Windows, jest jedna właściwość, którą należy ustawić
true
w konstruktorze usługi. Po prostu dodaj linię w konstruktorze:I pamiętaj, aby nie ustawiać tej właściwości po uruchomieniu usługi, w przeciwnym razie
InvalidOperationException
zostanie wyrzucony.źródło
Poniżej znajduje się w 100% działający kod, aby sprawdzić, czy komputer jest zablokowany, czy nie.
Przed użyciem tego użyj przestrzeni nazw
System.Runtime.InteropServices
.źródło