通过代码(C#)可以编程地开关显示器吗?
通过代码(C#)可以编程地开关显示器吗?
你有没有试过谷歌一下?
第一个结果是:http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx
我不意外你需要使用一些由Windows提供的DLL文件。
(我猜你需要C#的解决方案,因为这是你唯一添加的标签)。
编辑于2013年2月8日:
有人提到该解决方案在Windows 7和8下不再适用。那么这里是一个可以在Windows 7下很好地工作的解决方案,尚未尝试过Windows 8。
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);
}
}
}
按下开关按钮
如果你想在代码中实现,Win32 API似乎可以达成这个目的:
SendMessage hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, param
其中 WM_SYSCOMMAND = 0x112,SC_MONITORPOWER = 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));
}
注意,我实际上没有尝试过这个...
上面的回答https://dev59.com/hnRB5IYBdhLWcg3wH0SW#713504非常适用于关闭Windows 7/8的显示器,但不适用于唤醒它。在这些系统上,您需要执行类似于这样的hackish操作(如发现的https://dev59.com/GGcs5IYBdhLWcg3wynDD#14171736):
[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);
}
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)
- Doin对于希望在控制台应用上实现此功能的用户:
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);
}
}
已适配并测试。在Windows 8上百分之百工作。
HWND_BROADCAST
和PostMessage()
。 - CrazyIvan1974这段代码可以用于开启和关闭操作。它在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);
}
要调用该函数,您必须像这样执行:
SetMonitorState(MonitorState.ON);
SetMonitorState(MonitorState.OFF);
注意:此代码在WPF应用程序中进行了测试。使用以下命名空间:
using System.Runtime.InteropServices;
using 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);
}
}
}
}
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日),我正在运行:
我的系统完全是最新的。
代码行最少的答案:
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,使用SendInput()发送“ALT”也可以工作,但实现起来更加繁琐。