¿Cómo se puede determinar, en código, cuánto tiempo está bloqueada la máquina?
Otras ideas fuera de C # también son bienvenidas.
Me gusta la idea del servicio de Windows (y la he aceptado) por su simplicidad y limpieza, pero desafortunadamente no creo que funcione para mí en este caso particular. Quería ejecutar esto en mi estación de trabajo en el trabajo en lugar de en casa (o además de en casa, supongo), pero está bloqueado bastante por cortesía del Departamento de Defensa. En realidad, esa es parte de la razón por la que estoy rodando el mío.
Lo escribiré de todos modos y veré si funciona. ¡Gracias a todos!
Crearía un servicio de Windows (un tipo de proyecto de Visual Studio 2005) que maneja el evento OnSessionChange como se muestra a continuación:
Qué y cómo registra la actividad en ese momento depende de usted, pero un servicio de Windows proporciona un acceso rápido y fácil a los eventos de Windows como inicio, apagado, inicio de sesión / salida, junto con los eventos de bloqueo y desbloqueo.
fuente
La siguiente solución utiliza la API Win32. OnSessionLock se llama cuando la estación de trabajo está bloqueada y OnSessionUnlock cuando está desbloqueada.
fuente
Sé que esta es una pregunta antigua, pero encontré un método para obtener el estado de bloqueo para una sesión determinada.
Encontré mi respuesta aquí, pero estaba en C ++, así que traduje todo lo que pude a C # para obtener el estado de bloqueo.
Así que aquí va:
Nota: El código anterior se extrajo de un proyecto mucho más grande, así que si me perdí un poco, lo siento. No he tenido tiempo de probar el código anterior, pero planeo volver en una semana o dos para comprobarlo todo. Solo lo publiqué ahora porque no quería olvidarme de hacerlo.
fuente
if (session_info_ex.Level != 1)
- si la condición es verdadera, la memoria no se liberará. 2. si session_info_ex.Level! = 1 no debe hacer esto:Marshal.PtrToStructure<WTSINFOEX>(ppBuffer);
porque el tamaño del búfer devuelto puede diferir del tamaño de WTSINFOEXUInt32 Reserved;
sino que debe definir la estructuraWTSINFOEX_LEVEL1
completamente. En este caso, el compilador hará el relleno (alineación) correcto de los campos dentro de la estructura. 4. La funciónWTSFreeMemoryEx
se utiliza incorrectamente aquí.WTSFreeMemory
debe utilizarse en su lugar.WTSFreeMemoryEx
está destinado a liberar memoria despuésWTSEnumerateSessionsEx
.CharSet = CharSet.Auto
debe usarse en todos los atributos.Si está interesado en escribir un servicio de Windows para "encontrar" estos eventos, topshelf (la biblioteca / marco que facilita mucho la escritura de servicios de Windows) tiene un gancho.
y ahora el código para conectar el servicio de estante superior a la interfaz / concreto arriba
Todo lo que se muestra a continuación es una configuración "típica" de estante superior ... excepto por 2 líneas que marqué como
/ * ESTA ES MAGIC LINE * /
Esos son los que hacen que se active el método SessionChanged.
Probé esto con Windows 10 x64. Bloqueé y desbloqueé mi máquina y obtuve el resultado deseado.
My packages.config para proporcionar sugerencias sobre las versiones:
fuente
x.EnableSessionChanged();
junto con laServiceSessionChange
implementación de la interfaz si ha implementadoServiceControl
y no crea una instancia de clase de servicio implícita. Al igualx.Service<ServiceImpl>();
. Tienes que implementarServiceSessionChange
enServiceImpl
clase:class ServiceImpl : ServiceControl, ServiceSessionChange
NOTA : Esta no es una respuesta, sino una (contribución) a la respuesta de Timothy Carter , porque mi reputación no me permite comentar hasta ahora.
En caso de que alguien haya probado el código de la respuesta de Timothy Carter y no haya logrado que funcione de inmediato en un servicio de Windows, hay una propiedad que debe configurarse
true
en el constructor del servicio. Simplemente agregue la línea en el constructor:Y asegúrese de no establecer esta propiedad después de que se inicie el servicio, de lo contrario
InvalidOperationException
, se lanzará un error.fuente
A continuación se muestra el código de trabajo 100% para saber si la PC está bloqueada o no.
Antes de usar esto, use el espacio de nombres
System.Runtime.InteropServices
.fuente