C# 打开/关闭监视器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/713498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 22:11:21  来源:igfitidea点击:

Turn on/off monitor

c#winapi

提问by RV.

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

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

回答by Lee

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

注意我还没有真正尝试过这个......

回答by Wim Haanstra

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

回答by Quinxy von Besiex

The answer https://stackoverflow.com/a/713504/636189above 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):

上面的答案https://stackoverflow.com/a/713504/636189非常适合关闭 Windows 7/8 显示器,但不适用于唤醒它。在这些系统上,您需要做一些像这样的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);
}

回答by Saleh Parsa

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. With the below namespaces:

注意:此代码在 WPF 应用程序中进行了测试。使用以下命名空间:

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

回答by tkpb

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 上工作。

回答by Mike

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

我已经完成了每个人发布的让显示器进入睡眠状态并稍后在其他时间唤醒它的每一种方法。授予它SendMessage()确实适用于 Windows XP,但在显示器休眠一段时间后它不会唤醒显示器。我曾尝试使用 C#、DOS、用于处理电源配置文件的脚本和 Powershell。最终我放弃了并回到了起点,我的第一个想法被证明是正确的。您需要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
  • Visual Studio Profesional 2013 Version 12.0.31101.00 Update 4
  • .NET Framework 4.5.51209
  • C#
  • Windows 7 专业版 6.1.7601 Service Pack 1 Build 7601
  • Visual Studio Professional 2013 版本 12.0.31101.00 更新 4
  • .NET 框架 4.5.51209
  • C#

My system is completely up to date.

我的系统是完全最新的。

回答by klaasjan69

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

回答by Greg

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