C# Monitor aus dem Standby aufwecken

Mathias09876

Ensign
Registriert
Nov. 2010
Beiträge
235
Hallo zusammen,

ich würde gerne aus meinem Programm raus den Monitor aus dem Standby aufwecken.
Das Programm soll durchgehend laufen, allerdings ist es nicht nötig, dass die Monitore die ganze Zeit an sind. Bei bestimmten Ereignissen würde ich sie allerdings gerne wieder aktivieren.

Eine Google-Suche hat bisher nichts brauchbares ergeben. Das einzige was ich gefunden habe wäre den Mauszeiger per Programm zu verschieben. Allerdings habe ich das noch nicht ausprobiert und eigentlich müsste das doch eleganter gehen oder?

Hoffe Ihr habt die ein oder andere Idee oder Lösung für mein Problem :)
Achja ich es handelt sich um ein WPF Projekt.

Danke!

Grüße
Mathias
 
Zuletzt bearbeitet: ([edit] Habe vergessen zu erwähnen, dass ich mit WPF arbeite)
Hab momentan leider gerade nicht die Möglichkeit das selbst zu testen. Google hat bei mir allerdings etwas ausgespuckt was ich kurz überflogen habe und soweit gut aussieht.

http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx
http://www.c-sharp-forum.de/topic_Monitor+in+StandBy+schicken_81739,0.html

Der zweite Link ist sogar aus einem deutschen Forum und das Problem konnte gelöst werden. Der User möchte zwar den Standby-Mode aktivieren und nicht deaktivieren wie du, aber vermutlich musst du dazu nur eine einzelne Code-Zeile ändern.

Gruss
 
Zuletzt bearbeitet: (Typos)
Hi,

danke für die Links, leider funktioniert es nicht richtig.
Die Funktion zum aktivieren der Bildschirme wird in der Eventroutine eines FileSystemWatcher-Objekts aufgerufen. Das heißt, wenn sich eine Datei ändert sollen die Monitore aktiviert werden.
Beim ersten Aufruf würden sich die Monitore schon aktivieren nur leider werden sie sofort wieder deaktiviert. Erst wenn ich das Event noch einmal auslöse (ich füge übers Netzwerk eine neue Datei hinzu) wachen beide Bildschirme wieder auf.

Es würde also Prinzipiell gehen, auch wenn es ein ziemlicher Klimmzug ist aber ich verstehe nicht, warum es erst beim zweiten mal geht und beim ersten mal die Monitore gleich wieder in den Standby versetzt werden.

Hier mal mein Code:

Code:
        private void DisplayOn_SendMessage() {
            const int display_on = -1;

            const int WM_SYSCOMMAND = 0x0112;
            const int SC_MONITORPOWER = 0xF170;

            try {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate() {
                    IntPtr windowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;

                    SendMessage(windowHandle, WM_SYSCOMMAND, new IntPtr(SC_MONITORPOWER), new IntPtr((display_on)));
                });
            } catch (Exception ex) {
                Logger.WriteError("Couldnt activate display: " + ex.ToString());
            }
        }

Der Umweg über den Dispatcher war notwendig, da die Funktion aus einem anderen Thread aufgerufen wird und dann aber nicht das Handle des Fensters ermitteln kann. Zumindest ist das Programm bei dem Aufruf einfach abgestürzt.

Es würde ja auch funktionieren aber leider erst auf den zweiten Anlauf und das ist eher unbefriedigend ^^

Hoffe hier weiß noch jemand Rat.

[EDIT:]

Ich habe gerade mal versucht was passiert, wenn mein Programm den Standby aktiviert und nicht Windows selbst: Dann geht es einwandfrei...
Warum brauchts es aber dann zwei Anläufe, wenn der Standby von Windows kommt?

Mir fällt momentan keine Lösung ein, wie ich mir das zu Nutzen machen kann. Der Rechner ist mehreren Zugänglich und es kann gut sein, dass auch mal eine Powerpoint o.ä. läuft.
Sollte jetzt jemand vergessen die Bildschirme über mein Programm zu deaktivieren wird Windows das nach einer Zeit x machen und mein Programm kann sie dann nicht wieder aufwecken.
Hat hierzu zufällig noch jemand eine Idee, wie ich es erzwingen kann, dass die Bildschirme durch mein Programm deaktiviert werden? Dann müsste es nämlich gehen.
 
Zuletzt bearbeitet:
Wenn dein Programm das Display benötigt, dann wäre es imo am besten, wenn du Windows das einfach mitteilst. Den Rest (also Monitor anschalten und solange an lassen, bis er nicht mehr benötigt wird) erledigt Windows dann selbst.

Dafür gibts ne Win API Funktion: SetThreadExecutionState function
In C# umgesetzt: pinvoke: SetThreadExecutionState

Wenn du das Display nicht mehr brauchst, musst du das aber ebenfalls über diese Funktion festlegen, sonst geht das Display nicht mehr in den Standby (und der Bildschirmschoner bleibt auch deaktiviert).
 
Zuletzt bearbeitet:
Perfekt, vielen Dank Grantig, das war genau das, was ich gesucht habe!
Funktioniert einwandfrei :)

Nur eine Frage hab ich noch zu den Beispielen beim zweiten Link:

Was macht diese Oder-Verknüpfung? Bzw. warum steht da nicht nur ein EXECUTION_STATE.ES_DISPLAY_REQUIRED?

Code:
    void PreventMonitorPowerdown ()
    {
        SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
    }
 
Funktioniert einwandfrei
Na klar^^
Genauso unterdrückt auch NoSleep! den Bildschirmschoner oder den Standby (siehe Sig ;))

Das EXECUTION_STATE.ES_CONTINUOUS Flag sagt Windows, dass die Einstellung bestehen bleiben soll, bis man sie widerruft.
Du kannst die Funktion auch nur mit EXECUTION_STATE.ES_DISPLAY_REQUIRED aufrufen, dann wird nur der Idle Timer resettet. (--> wenn der Idle Timer ne bestimmte Schwelle erreicht hat, wird der Monitor in den Standby versetzt)

Warum das mit OR verknüpft wird?
Weil das Flags sind, die du da übergibst.
 
Grantig schrieb:
Na klar^^
Das EXECUTION_STATE.ES_CONTINUOUS Flag sagt Windows, dass die Einstellung bestehen bleiben soll, bis man sie widerruft.
Du kannst die Funktion auch nur mit EXECUTION_STATE.ES_DISPLAY_REQUIRED aufrufen, dann wird nur der Idle Timer resettet. (--> wenn der Idle Timer ne bestimmte Schwelle erreicht hat, wird der Monitor in den Standby versetzt)

Das heißt wenn ich nur den ES_DISPLAY_REQUIRED aufrufe würde er wenn die Energieeinstellung von Windows auf 10min steht nach den 10min den Bildschirm wieder abschalten?
Das ich Flags Or Verknüpfen muss war mir klar ^^ es ging nur um die Kombination der beiden Flags, was die bewirkt.

Danke
 
Das heißt wenn ich nur den ES_DISPLAY_REQUIRED aufrufe würde er wenn die Energieeinstellung von Windows auf 10min steht nach den 10min den Bildschirm wieder abschalten?
Genau das. (Vorausgesetzt der Nutzer macht in der Zwischenzeit nichts)

Das ich Flags Or Verknüpfen muss war mir klar ^^
Sorry, du hast nach der Verknüpfung gefragt, deswegen dachte ich du weiß das nicht ;)
 
Grantig schrieb:
Genau das. (Vorausgesetzt der Nutzer macht in der Zwischenzeit nichts)

Das ist ja noch viel perfekter :D
Die Funktion ist absolut das, was ich gesucht habe ^^

Grantig schrieb:
Sorry, du hast nach der Verknüpfung gefragt, deswegen dachte ich du weiß das nicht ;)

Kein Ding, war von mir etwas ungeschickt formuliert ^^

Du hast mir auf jeden Fall den Tag/Abend gerettet ;)
 
Zurück
Oben