Turn on/off monitor

C#Winapi

C# Problem Overview


Is it programmatically possible to turn a monitor on/off through code (C#)?

C# Solutions


Solution 1 - C#

Did you even try googling it?

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

I am not surprised you need to use some DLL's supplied by Windows.

(I guessed you needed a C# solution, because that's the only tag you applied).

EDIT February 8th 2013:

It was mentioned that the solution no longer worked under Windows 7 en 8. Well here is one that works nicely under Windows 7, haven't tried Windows 8 yet.

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

Solution 2 - C#

Press the on/off button


If you want to do it in code, apparently this is possible in the Win32 API:

SendMessage hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, param

where WM_SYSCOMMAND = 0x112 and SC_MONITORPOWER = 0xF170 and param indicates the mode to put the monitor in: -1 : on 2 : off 1 : energy saving mode

hWnd can be a handle for any window - so if you have a Form, something like this should work

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

Note I haven't actually tried this...

Solution 3 - C#

The answer https://stackoverflow.com/a/713504/636189 above works great for turning off a Windows 7/8 monitor but not for waking it up. On those systems you'll need to do something hackish like this (as found 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);
}

Solution 4 - C#

For who wants this functionality on a console application:

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 and tested. 100% working on Windows 8.

Solution 5 - C#

This code can be useful for turning on and turning off.. It worked in Windows 7 also.

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

    }

For calling the function you must do like:

SetMonitorState(MonitorState.ON);

OR

SetMonitorState(MonitorState.OFF);

Note: This code tested in WPF Application. With the below namespaces:

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

Solution 6 - C#

I could not find a copy paste example, so created one myself, dont forget to add a reference to 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);
            }
        }
    }
}

Solution 7 - C#

I have gone through every single method that everyone has published for putting a monitor to sleep and waking it later at some other time. Granted the SendMessage() does work with Windows XP but it doesn't wake the monitor after the monitor has been a sleep for a period of time. I have tried using C#, DOS, scripts for playing with power profiles, and Powershell. Eventually I gave up and went back to the beginning and my first thought was proven correct. You need to use the PostMessage() after the monitor has been turned off, better yet, you should probably always use PostMessage();


So all the code that you have seen before is correct, instead use the following:

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

At this time of execution and working appropriately (May 11, 2015) I am running

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

My system is completely up to date.

Solution 8 - C#

The answer with the least 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);
    }
}

Solution 9 - C#

For Windows 10 (tested on Pro 64 bits), I was able to turn off the monitor using the SendMessage() technique mentioned in this page. However, impossible for me to turn the monitor back on: the "mouse move" trick did not work, the SendMessage() technique would turn the screen back on for one second then back off and using PostMessage() did not change anything.

But the trick is in fact really simple, all I had to do was simulate a keypress with SendKeys(). I'm using ALT here because in itself it has no impact on the system but it could be any other key.

SendKeys.SendWait("%");

If you're not using Windows.Forms, sending "ALT" also works using SendInput() but it's longer to implement.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRV.View Question on Stackoverflow
Solution 1 - C#Wim HaanstraView Answer on Stackoverflow
Solution 2 - C#LeeView Answer on Stackoverflow
Solution 3 - C#Quinxy von BesiexView Answer on Stackoverflow
Solution 4 - C#tkpbView Answer on Stackoverflow
Solution 5 - C#Saleh ParsaView Answer on Stackoverflow
Solution 6 - C#klaasjan69View Answer on Stackoverflow
Solution 7 - C#MikeView Answer on Stackoverflow
Solution 8 - C#GregView Answer on Stackoverflow
Solution 9 - C#fvlindenView Answer on Stackoverflow