2009-04-03 19 views
42

¿Es programáticamente posible encender/apagar un monitor mediante el código (C#)?Encender/apagar el monitor

+2

Adición de "programación" en alguna parte de su pregunta que puede salvar de las downvotes .. mi 2 céntimos :-) – Newtopian

+0

estuvo de acuerdo con anterior: aunque este doesn No gano el premio de "buena pregunta", personalmente estoy en desacuerdo con tantos votos a la baja. En realidad es una pregunta válida. – Razzie

+2

Todos piensan que son más inteligentes que el OP y conocen su problema. Vinoth no preguntó cómo hacerlo con un botón, le preguntó si era posible con el código ... – Inisheer

Respuesta

16

Pulse el botón de encendido/apagado


Si desea hacerlo en el código, al parecer, esto es posible en la API Win32:

SendMessage CVent, WM_SYSCOMMAND, SC_MONITORPOWER, parámetro

donde WM_SYSCOMMAND = 0x112 y SC_MONITORPOWER = 0xF170 y PARAM indica el modo de poner el monitor en: -1: en 2: off 1: Modo de ahorro de energía

CVent puede ser un mango para cualquier ventana - por lo que si usted tiene una forma, algo como esto debería funcionar

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)); 
} 

Nota No he En realidad, lo intenté ...

+1

Si se corta la alimentación, puede ser demasiado oscuro para ver el encendido/botón de apagado, por lo que es posible que necesite tener una linterna a mano para esas condiciones. –

+1

¡Yo quería responder esto, +1 :-) – Newtopian

+0

si eso funciona, entonces la respuesta perfecta! – Hugo

29

¿Incluso trataste de googlearlo?

primer éxito: http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

No me sorprende es necesario utilizar alguna DLL suministrado por Windows.

(Supuse que necesitabas una solución C#, porque esa es la única etiqueta que aplicaste).

EDITAR octavo de febrero de 2013:

Se mencionó que la solución ya no funcionaba en Windows 7 en 8. También aquí es uno que funciona muy bien con Windows 7, no se han probado Windows 8 todavía.

http://cocoa.ninja/posts/Turn-off-your-monitor-in-Csharp.html

namespace MonitorOff { 

    public enum MonitorState { 
     MonitorStateOn = -1, 
     MonitorStateOff = 2, 
     MonitorStateStandBy = 1 
    } 

    public partial class Form1 : Form { 
     [DllImport("user32.dll")] 
     private static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam); 

     public Form1() { 
      InitializeComponent(); 
      SystemEvents.SessionSwitch += SystemEvents_SessionSwitch; 
     } 

     void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) { 
      SetMonitorInState(MonitorState.MonitorStateOff); 
     } 

     private void button1_Click(object sender, EventArgs e) { 
      SetMonitorInState(MonitorState.MonitorStateOff); 
     } 

     private void SetMonitorInState(MonitorState state) { 
      SendMessage(0xFFFF, 0x112, 0xF170, (int)state); 
     } 
    } 
} 
+1

Ese ejemplo de Code Project no funciona en Windows 7 u 8. –

+0

¿Sabía que esta respuesta se dio en 2009? –

+18

Sí, pero como la respuesta aún está altamente clasificada en Google en 2013, pensé que otros como yo vendrían, verían esto, irían a descargar y probarían el proyecto solo para descubrir que no funciona en los sistemas operativos Windows posteriores a 2009. Estaba tratando de salvarlos los más de 10 minutos. De ninguna manera intento quitarle el valor agregado a su respuesta, estoy seguro de que ayudó a miles de personas, solo estoy tratando de hacerle saber a las personas que algo ha cambiado. –

13

La respuesta https://stackoverflow.com/a/713504/636189 anterior funciona muy bien para apagar un monitor de Windows 7/8 pero no para despertándolo. En aquellos sistemas que necesita para hacer algo como esto hacker (como se encuentra 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); 
} 
+0

Esta solución funcionó muy bien en Windows Vista, con dos monitores. –

+0

Con tan solo 2 centavos, mouse_event no funciona para mantener al MS Office Communicator en estado "activo", solo haga clic con el mouse y keybd_event, por lo que podría ser una prueba más futura usarlos o mover el mouse más de un píxel en caso de que alguien piensa: "Debemos dejar de encender los monitores cuando alguien golpea su escritorio". – Motes

+0

La respuesta aceptada anteriormente no funcionaba para mí en Windows 10. La respuesta aceptada activaría la pantalla brevemente, pero luego se apagaría. Esto fue en un Surface Pro. Una vez que implementé esta solución, funcionó de maravilla. Hackish, sí, pero funciona y eso es lo suficientemente bueno para las chicas con las que salgo. – jaredbaszler

8

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

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 las llamadas a la función que debe hacer como:

SetMonitorState(MonitorState.ON); 

O

SetMonitorState(MonitorState.OFF); 

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

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

para quien quiera 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); 
    } 
} 

Adaptated y probado. 100% trabajando en Windows 8.

+1

No es necesario llamar a GetConsoleWindow, ni para obtener un GUI hwnd en una aplicación que no es de consola, solo use el mensaje HWND_BROADCAST en su lugar (** SendMessage (New IntPtr (0xFFFF) ** ...). – ElektroStudios

3

He revisado todos y cada uno de los métodos que todos han publicado para poner un monitor en modo de suspensión y despertarlo más tarde en otro momento. De acuerdo, el 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. Debe usar el PostMessage() después de apagar el monitor; mejor aún, probablemente siempre deba usar PostMessage();


Así que todo el código que haya visto antes es correcta, en lugar de utilizar el 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 trabajando apropiadamente (11 de mayo, 2015) Soy corriendo

  • Windows 7 Professional Versión 6.1.7601 Service pack 1 Build 7601
  • Visual Studio Profesional 2013 Versión 12.0.31101.00 Update 4
  • .NET Framework 4.5.51209
  • C#

Mi sistema es completamente al día.

+0

Hola @Mike , Probé su solución y mis monitores se apagaron, pero después de 1 segundo o así se iluminan nuevamente. Intenté con PostMessage y SendMessage. (Windows 7 6.1.7601 x64) ¿Alguna idea? – ZeroDotNet

5

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); 
      } 
     } 
    } 
} 
+0

Funcionó para mí en la ventana 10 64 bit. Incluso creó un pequeño servidor de nodos que lo usa y ahora puedo apagar las pantallas de mi móvil. Muchas gracias. Por cierto, la apertura también funcionó, pero si ejecuto el comando de cerrar por segunda vez, incluso si está cerrado, se abriría. que me importa –

0

La respuesta con la menor 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); 
    } 
} 
+1

en mi humilde opinión no es mejor que la respuesta de klaasjan69 de 2011. Es más corto, pero menos legible. Responde solo al caso "apagado", pero no al "encendido". No veo "menos" SLOC "como una ventaja. –