C# 打开/关闭监视器

C# 打开/关闭监视器,c#,winapi,C#,Winapi,是否可以通过代码(C#)以编程方式打开/关闭监视器?按下打开/关闭按钮 如果您想在代码中执行此操作,那么在Win32 API中显然可以做到这一点: SendMessage hWnd,WM_SYSCOMMAND,SC_MONITORPOWER,参数 其中WM_SYSCOMMAND=0x112和 SC_监视器电源=0xF170和 param表示将监视器置于的模式: -1:在 2:关 1:节能模式 hWnd可以是任何窗口的句柄-因此,如果您有一个表单,类似这样的东西应该可以工作 int WM_SYS

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

按下打开/关闭按钮


如果您想在代码中执行此操作,那么在Win32 API中显然可以做到这一点:

SendMessage hWnd,WM_SYSCOMMAND,SC_MONITORPOWER,参数

其中WM_SYSCOMMAND=0x112和 SC_监视器电源=0xF170和 param表示将监视器置于的模式: -1:在 2:关 1:节能模式

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

注意,我实际上还没有试过这个…

你有没有试过用谷歌搜索它

首击:

我并不奇怪你需要使用Windows提供的一些DLL

(我猜您需要一个C#解决方案,因为这是您应用的唯一标记)

编辑2013年2月8日:

有人提到,该解决方案在Windows 7 en 8下不再有效。这里有一个可以在Windows7下很好地工作,但还没有试过Windows8

上面的答案对于关闭Windows 7/8显示器非常有效,但对于唤醒它却没有效果。在这些系统上,您需要做一些像这样的黑客行为(如发现的):


此代码可用于打开和关闭。。它在Windows7中也能工作

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

    }
要调用函数,必须执行以下操作:

SetMonitorState(MonitorState.ON);

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

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

对于希望在控制台应用程序上使用此功能的用户

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

适应和测试。100%在Windows 8上工作。

我经历了每个人发布的让显示器进入睡眠状态并在以后某个时间唤醒它的每一种方法。假定
SendMessage()
可以在Windows XP中使用,但在监视器睡眠一段时间后,它不会唤醒监视器。我尝试过使用C#、DOS、用于播放电源配置文件的脚本和Powershell。最终我放弃了,回到了起点,我的第一个想法被证明是正确的。您需要在显示器关闭后使用
PostMessage()
,更好的是,您可能应该始终使用
PostMessage()


因此,您以前看到的所有代码都是正确的,请使用以下代码:

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

在执行和正常工作的这段时间(2015年5月11日),我正在跑步

  • Windows 7专业版6.1.7601 Service Pack 1版本7601
  • Visual Studio Professional 2013版本12.0.31101.00更新4
  • .NET Framework 4.5.51209
  • #

我的系统完全是最新的。

我找不到复制粘贴示例,所以我自己创建了一个,别忘了添加对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);
            }
        }
    }
}

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);
    }
}
对于Windows 10(在Pro 64位上测试),我能够使用本页中提到的
SendMessage()
技术关闭显示器。 然而,我不可能重新打开显示器:鼠标移动的技巧不起作用,
SendMessage()
技术会将屏幕重新打开一秒钟,然后关闭,并且使用
PostMessage()
不会改变任何事

但是这个技巧实际上非常简单,我所要做的就是用
SendKeys()
模拟按键。我在这里使用ALT是因为它本身对系统没有影响,但它可以是任何其他键

SendKeys.SendWait("%");

如果您不使用Windows.Forms,发送“ALT”也可以使用,但它的实现时间较长。

如果电源断开,可能会因为太暗而看不到“开/关”按钮,因此您可能需要手电筒来适应这些情况。我很想回答这个问题,+1:-)关闭显示器效果很好,但我似乎无法打开它。关闭显示器在Windows 10中可以工作,但是再次尝试打开它会导致短暂的打开(大约一秒钟),然后再次变黑。如果两个显示器连接,是否可以打开/关闭第一和第二个显示器?在问题的某个地方添加“编程”可能会使您免于被否决。。我的2美分:-)同意上面的观点:虽然这没有赢得“好问题”奖,但我个人不同意这么多的反对票。这实际上是一个有效的问题。每个人都认为他们比OP更聪明,并且知道他/她的问题。Vinoth没有问如何使用按钮,他/她问是否可以使用代码……这是Vinoth提出的一个非常典型的问题,尽管他不断地提出评论和有用的提示,提示他提出更好的问题,但他仍然会抛出一些问得不好的模棱两可的问题。@Binary,我不同意你的看法。这不是胡扯,你可以回答这个问题,而不是试图否决这个简单的问题。你知道这个答案是在2009年给出的吗?我知道,但由于2013年这个答案在谷歌排名仍然很高,我想其他人也会像我一样出现,看这个,下载并尝试该项目,结果发现它在2009年后的Windows操作系统中不起作用。我试着给他们留10多分钟。我决不是想剥夺你的答案所增加的价值,我确信它帮助了成千上万的人,我只是想让人们知道有些东西已经改变了。第二个链接现在断了。也可以看到类似的答案:在win 10中,这会让所有显示器进入“睡眠”状态,直到我移动鼠标。这个解决方案在Windows Vista上非常有效,有两个显示器。只需2美分,鼠标事件无法保持MS office Communicator处于“活动”状态,只有鼠标点击和按键事件,因此,实际使用这些功能或移动鼠标超过一个像素可能更能证明未来,以防有人认为,“当有人撞到他们的桌子时,我们应该停止打开显示器。”上面接受的答案在Windows 10上对我不起作用。被接受的答案会短暂打开屏幕,但随后又会关闭。这是在一个表面专业。一旦我实施了这个解决方案,它就非常有效。Hackish,是的,但它很有效,这对女孩来说已经足够好了
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);
            }
        }
    }
}
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);
    }
}
SendKeys.SendWait("%");