
Después de haberme dado por vencido durante meses, me gustaría retomar la idea que parece tan increíblemente simple. Quiero tener un script que despierte mis monitores después de que fueron puestos en suspensión. Intenté casi cualquier enfoque que se me ocurra, por favor, que alguien me salve de adoptar un perro que busca un mouse bluetooth con forma de hueso y lo mueve en el proceso (sí, así de desesperado estoy)
Lo que hice hasta ahora:
1) Instalación de OpenSSH en la máquina Win10 remota (funciona)
2)Conseguirla sesión interactiva de Windows para tener autoridad sobre la sesión real:
FOR /F "usebackq tokens=4" %s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO ...
3a) Iniciar uno de losmuchosmantener los programas de Windows despiertos. Esos no funcionan porque psexec o powershell nunca los inician. O al menos si se ejecutan, no se muestran y no hacen nada. Eso es para cualquier proceso que intento iniciar.
3b) Úselo SendMessage
como lo hago yo para enviarlo a dormir:
psexec -accepteula -nobanner -d -i %%s -w "%windir%" powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,-1)
Pasar 2 como último parámetro funciona perfecto para apagar el monitor. Pasar cualquier otra cosa (por ejemplo, -1 para ON) no hace nada.
3c) Ahora desesperado trato de hacer unSimulación de movimiento del ratón/pulsación de teclasetc.:
FOR /F "usebackq tokens=4" %%s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO psexec -accepteula -nobanner -d -i %%s -w "%windir%" powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, int dwExtraInfo);' -Name user32 -PassThru)::mouse_event(1,40,0,0,0)
Obras ejecutadas localmente con derechos elevados. Aparece PowerShell brevemente cuando se usa con SSH. No mueve el ratón.
3d) usando el viejo monitor nircmd.exe apagado o utilidades similares dedicadas para encender el monitor. Mismo resultado que 3a)
Muchos de los hilos vinculados tienen supuestas soluciones, pero ninguna me funciona. La única diferencia que puedo ver entre la ejecución del script localmente y la ejecución a través de ssh es que hay una salida de algo como
powershell started on <mywin10pc> with process ID xxxxx
Aparte de eso, no tengo forma de saber qué está pasando. Puse un echo 0 al final de los scripts para comprobar si se ejecutó o no. Siempre me da el 0. ¿Alguien tiene una idea de lo que me falta? Especialmente 3b) me resulta extraño ya que funciona para poner el monitor en modo de suspensión.
Respuesta1
El problema es que activar el monitor y configurar la computadora en un estado activo son dos cosas diferentes. Enviando -1 para activar el monitorhaceactive la pantalla. Desafortunadamente, tampoco es suficiente para reactivar la computadora. Para esto puedes usar SetThreadExecutionState
. Aquí hay un ejemplo de lote funcional:
@ECHO OFF
:: gather session handle
FOR /F "usebackq tokens=4" %%s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO SET hsession=%%s
:: wake display
psexec -accepteula -nobanner -d -i %hsession% -w "%windir%" powershell -NoProfile -NoLogo -Command "(Add-Type '[DllImport(\"user32.dll\")]public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,-1)"
CALL :wait 2
:: reactivate session
psexec -accepteula -nobanner -d -i %hsession% -w "%windir%" powershell -NoProfile -NoLogo -Command "$x=Add-Type '[DllImport(\"kernel32.dll\")]public static extern void SetThreadExecutionState(uint esFlags);' -name System -namespace Win32 -passThru;$x::SetThreadExecutionState([uint32]\"0x03\");Sleep 5;$x::SetThreadExecutionState([uint32]\"0x40\");"
CALL :wait 2
GOTO:EOF
:wait
SET dowait=%~1
IF "%dowait%"=="" SET dowait=10
ping -n %dowait% 127.0.0.1 >NUL
GOTO:EOF
En algunos entornos es posible utilizar solo los SetThreadExecutionState
comandos, pero en mis pruebas no es 100% confiable. Esto tampoco activará los dispositivos que no lo admitan.
Respuesta2
Es posible que estés pensando demasiado en esto. ¿Quieres simplemente mantener los monitores despiertos? ¿O desea específicamente que se enciendan sólo después de que se hayan apagado? He usado un programa llamadoMueve el ratónen el pasado. Simplemente mueve el mouse 1 píxel hacia la izquierda y hacia la derecha después de una duración que usted especifique. No notas el movimiento cuando estás usando el mouse, pero mantendrá las pantallas activas (y tiene el beneficio adicional de mostrarte como activo en la mayoría de las aplicaciones de mensajería instantánea como Lync o Slack).