简体   繁体   English

打开/关闭监视器

[英]Turn on/off monitor

是否可以通过代码(C#)以编程方式打开/关闭监视器?

Did you even try googling it?你甚至尝试过谷歌搜索吗?

First hit: http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx第一次点击: http : //www.codeproject.com/KB/cs/Monitor_management_guide.aspx

I am not surprised you need to use some DLL's supplied by Windows.您需要使用 Windows 提供的某些 DLL,我并不感到惊讶。

(I guessed you needed a C# solution, because that's the only tag you applied). (我猜您需要一个 C# 解决方案,因为这是您应用的唯一标签)。

EDIT February 8th 2013: 2013 年 2 月 8 日编辑:

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.有人提到该解决方案在 Windows 7 en 8 下不再有效。这是一个在 Windows 7 下运行良好的解决方案,还没有尝试过 Windows 8。

http://cocoa.ninja/posts/Turn-off-your-monitor-in-Csharp.html 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);
        }
    }
}

Press the on/off button按下开/关按钮


If you want to do it in code, apparently this is possible in the Win32 API:如果你想在代码中做到这一点,显然这在 Win32 API 中是可能的:

SendMessage hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, param SendMessage hWnd、WM_SYSCOMMAND、SC_MONITORPOWER、参数

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其中 WM_SYSCOMMAND = 0x112 和 SC_MONITORPOWER = 0xF170 参数表示将监视器置于的模式: -1 :开 2 :关 1 :节能模式

hWnd can be a handle for any window - so if you have a Form, something like this should work hWnd 可以是任何窗口的句柄 - 所以如果你有一个表单,这样的东西应该可以工作

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...注意我还没有真正尝试过这个......

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.上面的答案https://stackoverflow.com/a/713504/636189非常适合关闭 Windows 7/8 显示器,但不适用于唤醒它。 On those systems you'll need to do something hackish like this (as found https://stackoverflow.com/a/14171736/636189 ):在这些系统上,您需要做一些像这样的hackish(如发现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);
}

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. 100% 在 Windows 8 上工作。

This code can be useful for turning on and turning off.. It worked in Windows 7 also.此代码可用于打开和关闭。它也适用于 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);

    }

For calling the function you must do like:要调用该函数,您必须执行以下操作:

SetMonitorState(MonitorState.ON);

OR或者

SetMonitorState(MonitorState.OFF);

Note: This code tested in WPF Application.注意:此代码在 WPF 应用程序中进行了测试。 With the below namespaces:使用以下命名空间:

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

I could not find a copy paste example, so created one myself, dont forget to add a reference to System.Windows.Forms.我找不到复制粘贴示例,所以自己创建了一个,不要忘记添加对 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);
            }
        }
    }
}

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.授予SendMessage()确实适用于 Windows XP,但在监视器休眠一段时间后它不会唤醒监视器。 I have tried using C#, DOS, scripts for playing with power profiles, and Powershell.我曾尝试使用 C#、DOS、用于处理电源配置文件的脚本和 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() ;您需要在关闭监视器后使用PostMessage() ,更好的是,您应该始终使用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在执行和正常工作的这个时候(2015 年 5 月 11 日)我正在运行

  • Windows 7 Professional Version 6.1.7601 Service Pack 1 Build 7601 Windows 7 专业版 6.1.7601 Service Pack 1 Build 7601
  • Visual Studio Profesional 2013 Version 12.0.31101.00 Update 4 Visual Studio Professional 2013 版本 12.0.31101.00 更新 4
  • .NET Framework 4.5.51209 .NET 框架 4.5.51209
  • C# C#

My system is completely up to date.我的系统是完全最新的。

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

For Windows 10 (tested on Pro 64 bits), I was able to turn off the monitor using the SendMessage() technique mentioned in this page.对于 Windows 10(在 Pro 64 位上测试),我能够使用本页中提到的SendMessage()技术关闭显示器。 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.但是,我不可能重新打开显示器:“鼠标移动”技巧不起作用, SendMessage()技术会将屏幕重新打开一秒钟然后关闭,并且使用PostMessage()没有任何改变。

But the trick is in fact really simple, all I had to do was simulate a keypress with SendKeys() .但诀窍实际上非常简单,我所要做的就是使用SendKeys()模拟按键。 I'm using ALT here because in itself it has no impact on the system but it could be any other key.我在这里使用 ALT 是因为它本身对系统没有影响,但它可以是任何其他键。

SendKeys.SendWait("%");

If you're not using Windows.Forms, sending "ALT" also works using SendInput() but it's longer to implement.如果您不使用 Windows.Forms, 使用SendInput()发送“ALT”也有效,但实现时间更长。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM