Est-il possible par programme d'activer/désactiver un moniteur via du code (C #)?
Avez-vous même essayé de le googler?
Premier hit: http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx
Je ne suis pas surpris que vous ayez besoin d'utiliser certaines DLL fournies par Windows.
(Je suppose que vous aviez besoin d'une solution C #, car c'est la seule balise que vous avez appliquée).
EDIT 8 février 2013:
Il a été mentionné que la solution ne fonctionnait plus sous Windows 7 en 8. Eh bien, voici une qui fonctionne bien sous Windows 7, je n'ai pas encore essayé 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);
}
}
}
Appuyez sur le bouton marche/arrêt
Si vous voulez le faire en code, cela est apparemment possible dans l'API Win32:
SendMessage hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, param
où WM_SYSCOMMAND = 0x112 et SC_MONITORPOWER = 0xF170 et param indique le mode de mise en place du moniteur: -1: allumé 2: éteint 1: mode économie d'énergie
hWnd peut être une poignée pour n'importe quelle fenêtre - donc si vous avez un formulaire, quelque chose comme ça devrait fonctionner
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));
}
Notez que je n'ai pas vraiment essayé ça ...
La réponse https://stackoverflow.com/a/713504/636189 ci-dessus fonctionne très bien pour éteindre un moniteur Windows 7/8 mais pas pour le réveiller. Sur ces systèmes, vous devrez faire quelque chose de piraté comme celui-ci (comme trouvé 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);
}
Ce code peut être utile pour allumer et éteindre .. Il fonctionnait également sous 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);
}
Pour appeler la fonction, vous devez faire comme:
SetMonitorState(MonitorState.ON);
OR
SetMonitorState(MonitorState.OFF);
Remarque: Ce code testé dans WPF Application. Avec les espaces de noms ci-dessous:
using System.Runtime.InteropServices;
using System.Windows.Forms;
Pour qui veut cette fonctionnalité sur une application console:
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);
}
}
Adapté et testé. 100% fonctionnant sur Windows 8.
Je n'ai pas pu trouver d'exemple de copier-coller, alors j'en ai créé un moi-même, n'oubliez pas d'ajouter une référence à 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);
}
}
}
}
J'ai suivi toutes les méthodes que tout le monde a publiées pour mettre un moniteur en veille et le réveiller plus tard à un autre moment. Certes, la SendMessage()
fonctionne avec Windows XP mais elle ne réveille pas le moniteur après une veille prolongée du moniteur. J'ai essayé d'utiliser C #, DOS, scripts pour jouer avec les profils de puissance et Powershell. Finalement, j'ai abandonné et je suis retourné au début et ma première pensée s'est avérée correcte. Vous devez utiliser la PostMessage()
après avoir éteint le moniteur, mieux encore, vous devriez probablement toujours utiliser PostMessage()
;
Donc, tout le code que vous avez vu auparavant est correct, utilisez plutôt ce qui suit:
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);
En ce moment d'exécution et de travail approprié (11 mai 2015) je cours
Mon système est complètement à jour.
La réponse avec le moins de 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);
}
}