Turn on/off monitor
Asked Answered
S

9

64

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

Sammons answered 3/4, 2009 at 11:6 Comment(11)
Adding "programmatically" somewhere in your question may save you from the downvotes.. my 2 cent :-)Trustworthy
Agreed with above: though this doesn't win the 'nice question' award, I personally disagree with so many downvotes. It is actually a valid question.Connotative
Everyone thinks they are smarter than the OP and knows his/her problem. Vinoth didnt ask how to do it with a button, he/she asked if it were possible with code...Addia
This is a pretty typical question from Vinoth, despite repeated comments and helpful hints prompting him to ask better questions, he still trolls out poorly asked ambiguous questions.Leflore
@Binary, I don't agree with you. This is not trolling, you could give answer to question and not trying to downvote this simple question.Freeswimming
@tomaszs: That's cool, you are entitled to your opinion. I have seen some fairly spectacular trolling by a user called "Vinoth", in fairness, this may not be the same user, but the minimalist questions suggests to me that it is.Leflore
If this is for saving power, than i'm working for a large company that could save some power too...Relations
@James: One of the downsides of the ability to edit questions is that you can come to the party a bit late and miss something. The question was of poor quality to begin with hence the downvotes and less than helpful answersGadroon
For reference : The original question was - "hi i need to Turn on/off monitor.... how to do this..."Redhead
Anthony.. I understand... but I was the one who edited the question.Addia
Adding cross-reference: #2576931Interlard
I
26

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);
        }
    }
}
Imphal answered 3/4, 2009 at 11:9 Comment(8)
You do know that this answer has been given in 2009?Imphal
I do, but as the answer is still highly ranked in Google in 2013 I figured others like me will come along, see this, and go download and try the project only to discover it doesn't work in post-2009 Windows OSes. I was trying to save them the 10+ minutes. I am in no way trying to take away from the value your answer added, I'm sure it helped thousands of people, I'm just trying to let people know something has changed.Pleione
Second link now broken.Northcliffe
also see this similar answer: https://mcmap.net/q/303131/-how-to-turn-on-monitor-after-wake-up-from-suspend-mode-closedLabanna
And this is actually now the top result from Googling it.Terce
In win 10 this puts all the monitors into "sleep" until I move the mouse.Phonation
FYI this method to turn off the screen is a hack - you are trying to broadcast a message you don't control to all windows on the desktop? Microsoft explicitly doesn't support this behavior. You should never send messages that are explicitly documented as being messages sent only by the system. This may not work on future versions of Windows and you definitely shouldn't be broadcasting to all windows. Please avoid using this technique if possible.Bajaj
I don't know a possibility that this way causes posibility but I confirmed it works for turning OFF, turning ON way is: https://mcmap.net/q/300793/-turn-on-off-monitorPosset
B
20

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...

Bielefeld answered 3/4, 2009 at 11:8 Comment(6)
If the power is out, it may be too dark to see the on/off button, so you may need to have a flashlight handy for those conditions.Dusk
I sooo wanted to answer this, +1 :-)Trustworthy
It works great to turn the monitor off, but I can't seem to get it turn it on.Pleione
Turning monitor off works in Windows 10, however trying to turn it on again will result in a brief turnon (about a second), then black again.Hudak
Is it possible to turn on/off 1st and 2nd monitor if two monitors are connected?Detestation
See my comments on the top answer - this technique is a hack and should not be used since it's sending a message documented as being only something that should be sent by the system. The only thing worth noting is that at least this answer doesn't try to broadcast the message to all windows 😋.Bajaj
P
19

The answer https://mcmap.net/q/300793/-turn-on-off-monitor 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://mcmap.net/q/303132/-sendmessage-sc_monitorpower-won-39-t-turn-monitor-on-when-running-windows-8):

[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);
}
Pleione answered 5/2, 2013 at 0:53 Comment(4)
This solution worked great on Windows Vista, with two monitors.Wrightson
Just 2 cents, mouse_event doesn't work to keep MS office Communicator in "active" status, only mouse click and keybd_event, so it might be more future proof to actually use those or maybe move the mouse more than one pixel in case somebody thinks, "We should stop turning on monitors when someone bumps their desk."Marchall
Accepted answer above didn't work for me on Windows 10. The accepted answer would turn the screen on briefly but then it would go back off. This was on a Surface Pro. Once I implemented this solution it worked great. Hackish, yes, but it works and that's good enough for the girls I date!Superstar
If you're here looking for a way to do this in a .bat file or in a Task Scheduler action (say), rather than from C# then this answer: superuser.com/a/1371383 suggests a method. You can use the following to trigger a horizontal mouse movement of 40px that will turn the display back on if it's gone off due to inactivity: 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)Atworth
N
18

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.

Narda answered 25/3, 2014 at 14:5 Comment(4)
There is no need to call the GetConsoleWindow, neither to get a GUI hwnd on a non-console app, just use the HWND_BROADCAST message instead ( SendMessage(New IntPtr(0xFFFF)... ).Solorzano
Works on Windows 10 Home, with HWND_BROADCAST and PostMessage().Dombrowski
HWND_BROADCAST worked and also locked up for me on Windows 10, no idea why, might have been the multiple displays I had. GetConsoleWindow() worked though.Peden
Don't use HWND_BROADCAST, it'll cause every receiving app to try to suspend one after another.Annelieseannelise
C
12

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;
Chokeberry answered 11/1, 2014 at 7:19 Comment(0)
T
8

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);
            }
        }
    }
}
Touchdown answered 11/9, 2015 at 6:14 Comment(1)
Worked for me on window 10 64 bit. Even created a small nodejs server that uses it and now I can turn off the screens from my Mobile. Thanks a lot. BTW the opening also worked but if I run the close command a second time even if it is closed It would open. Not that it is matter to meOrthodox
A
3

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.

Alain answered 11/5, 2015 at 19:55 Comment(1)
Hi @Mike, I've tried your solution and my monitors went black but after 1 second or so they lights up again. Tried with PostMessage and SendMessage. (Windows 7 6.1.7601 x64) Any idea?Eagleeyed
L
3

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);
    }
}
Lengthwise answered 16/10, 2015 at 14:12 Comment(1)
IMHO not better than the answer by klaasjan69 from 2011. It is shorter, but less readable. It only answers the "off" case, but not the "on" case. I don't see "least SLOC" as an advantage.Merryman
E
2

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.

Evidently answered 19/6, 2020 at 8:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.