Attiva / distriggers il monitor

È programmaticamente ansible accendere / spegnere un monitor tramite codice (C #)?

Hai provato a cercarlo su google?

Primo hit: http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

Non mi sorprende che sia necessario utilizzare alcune DLL fornite da Windows.

(Ho immaginato che avevi bisogno di una soluzione C #, perché quello è l’unico tag che hai applicato).

EDIT 8 febbraio 2013:

È stato detto che la soluzione non funzionava più con Windows 7 e 8. Bene, eccone uno che funziona bene con Windows 7, ma non ho ancora provato Windows 8.

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

Premere il pulsante di accensione / spegnimento


Se vuoi farlo in codice, apparentemente questo è ansible nell’API Win32:

SendMessage hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, param

dove WM_SYSCOMMAND = 0x112 e SC_MONITORPOWER = 0xF170 e param indica la modalità per mettere il monitor in: -1: su 2: off 1: modalità di risparmio energetico

hWnd può essere un handle per qualsiasi finestra, quindi se hai un form, qualcosa del genere dovrebbe funzionare

 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 che in realtà non ho provato questo …

La risposta https://stackoverflow.com/a/713504/636189 funziona perfettamente per distriggersre un monitor di Windows 7/8 ma non per ritriggersrlo. Su quei sistemi dovrai fare qualcosa di hackish come questo (come trovato 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); } 

Questo codice può essere utile per l’accensione e lo spegnimento. Funzionava anche con 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); } 

Per chiamare la funzione devi fare come:

 SetMonitorState(MonitorState.ON); 

O

 SetMonitorState(MonitorState.OFF); 

Nota: questo codice è stato testato nell’applicazione WPF. Con i seguenti namespace:

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

Per chi vuole questa funzionalità su un’applicazione console :

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

Adattato e testato. 100% di lavoro su Windows 8.

Non sono riuscito a trovare un esempio di copia incolla, quindi ne ho creato uno io stesso, non dimenticare di aggiungere un riferimento 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); } } } } 

Ho esaminato ogni singolo metodo che tutti hanno pubblicato per mettere a rest un monitor e svegliarlo più tardi in un altro momento. Dato che SendMessage() funziona con Windows XP ma non ritriggers il monitor dopo che il monitor è rimasto inattivo per un periodo di tempo. Ho provato a usare C #, DOS, script per giocare con i profili di potenza e Powershell. Alla fine ho rinunciato e sono tornato all’inizio e il mio primo pensiero è stato dimostrato corretto. Devi usare PostMessage() dopo che il monitor è stato spento, meglio ancora, dovresti probabilmente usare sempre PostMessage() ;


Quindi tutto il codice che hai visto prima è corretto, invece usa il seguente:

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

In questo momento di esecuzione e lavorando in modo appropriato (11 maggio 2015) sono in esecuzione

  • Windows 7 Professional Versione 6.1.7601 Service Pack 1 Build 7601
  • Visual Studio Profesional 2013 Aggiornamento versione 12.0.31101.00 4
  • .NET Framework 4.5.51209
  • C #

Il mio sistema è completamente aggiornato.

La risposta con il minimo 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); } }