Enciende / apaga el monitor

¿Es programáticamente posible activar / desactivar un monitor a través del código (C #)?

Presione el botón de encendido / apagado


Si desea hacerlo en código, aparentemente esto es posible en la API de Win32:

SendMessage hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, param

donde WM_SYSCOMMAND = 0x112 y SC_MONITORPOWER = 0xF170 y param indica el modo para poner el monitor en: -1: en 2: apagado 1: modo de ahorro de energía

hWnd puede ser un identificador para cualquier ventana, por lo que si tiene un Formulario, debería funcionar algo como esto

 int WM_SYSCOMMAND = 0x112; int SC_MONITORPOWER = 0xF170; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); public static void Main(string[] args) { Form f = new Form(); bool turnOff = true; //set true if you want to turn off, false if on SendMessage(f.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)(turnOff ? 2 : -1)); } 

Tenga en cuenta que en realidad no he intentado esto …

La respuesta https://stackoverflow.com/a/713504/636189 anterior funciona muy bien para apagar un monitor de Windows 7/8 pero no para activarlo. En esos sistemas, tendrá que hacer algo así de hackear (como se encuentra en https://stackoverflow.com/a/14171736/636189 ):

 [DllImport("user32.dll")] static extern void mouse_event(Int32 dwFlags, Int32 dx, Int32 dy, Int32 dwData, UIntPtr dwExtraInfo); private const int MOUSEEVENTF_MOVE = 0x0001; private void Wake(){ mouse_event(MOUSEEVENTF_MOVE, 0, 1, 0, UIntPtr.Zero); Sleep(40); mouse_event(MOUSEEVENTF_MOVE, 0, -1, 0, UIntPtr.Zero); } 

Este código puede ser útil para encender y apagar. Funcionó también en Windows 7.

  private int SC_MONITORPOWER = 0xF170; private uint WM_SYSCOMMAND = 0x0112; [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); enum MonitorState { ON = -1, OFF = 2, STANDBY = 1 } private void SetMonitorState(MonitorState state) { Form frm = new Form(); SendMessage(frm.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)state); } 

Para llamar a la función debes hacer lo siguiente:

 SetMonitorState(MonitorState.ON); 

O

 SetMonitorState(MonitorState.OFF); 

Nota: Este código fue probado en la aplicación WPF. Con los siguientes espacios de nombres:

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

Para quién quiere esta funcionalidad en una aplicación de consola :

 using System; using System.Runtime.InteropServices; using System.Timers; namespace TurnScreenOFF { class Program { private static int WM_SYSCOMMAND = 0x0112; private static uint SC_MONITORPOWER = 0xF170; public static void Main(string[] args) { SendMessage(GetConsoleWindow(), WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)2); } [DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); } } 

Adaptado y probado. 100% trabajando en Windows 8.

No pude encontrar un ejemplo de copiar y pegar, así que creé uno, no olvide agregar una referencia a System.Windows.Forms.

 using System; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; namespace monitor_on_off { class Program { [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] static extern void mouse_event(Int32 dwFlags, Int32 dx, Int32 dy, Int32 dwData, UIntPtr dwExtraInfo); private const int WmSyscommand = 0x0112; private const int ScMonitorpower = 0xF170; private const int MonitorShutoff = 2; private const int MouseeventfMove = 0x0001; public static void MonitorOff(IntPtr handle) { SendMessage(handle, WmSyscommand, (IntPtr)ScMonitorpower, (IntPtr)MonitorShutoff); } private static void MonitorOn() { mouse_event(MouseeventfMove, 0, 1, 0, UIntPtr.Zero); Thread.Sleep(40); mouse_event(MouseeventfMove, 0, -1, 0, UIntPtr.Zero); } static void Main() { var form = new Form(); while (true) { MonitorOff(form.Handle); Thread.Sleep(5000); MonitorOn(); Thread.Sleep(5000); } } } } 

He revisado todos y cada uno de los métodos que todo el mundo ha publicado para poner un monitor a dormir y despertarlo más tarde en otro momento. De acuerdo, SendMessage() funciona con Windows XP pero no activa el monitor después de que el monitor ha estado inactivo por un período de tiempo. He intentado usar C #, DOS, scripts para jugar con perfiles de potencia y Powershell. Eventualmente me di por vencido y volví al principio y mi primer pensamiento fue probado como correcto. Necesita utilizar PostMessage() después de apagar el monitor, mejor aún, probablemente siempre deba usar PostMessage() ;


Entonces todo el código que ha visto antes es correcto, en su lugar use lo siguiente:

 using System.Runtime.InteropServices; [DllImport("user32.dll")] static extern IntPtr PostMessage(int hWnd, int msg, int wParam, int lParam); PostMessage(-1, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_OFF); 

En este momento de la ejecución y el trabajo adecuado (11 de mayo de 2015) estoy corriendo

  • Windows 7 Professional Version 6.1.7601 Service Pack 1 Build 7601
  • Visual Studio Profesional 2013 Versión 12.0.31101.00 Actualización 4
  • .NET Framework 4.5.51209
  • DO#

Mi sistema está completamente actualizado.

La respuesta con el mínimo de SLOC:

 using System; using System.Windows.Forms; using System.Runtime.InteropServices; static class Program { [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); [STAThread] static void Main() { SendMessage(new Form().Handle, 0x0112, 0xF170, 2); } }