Programme durch ausschalten des Monitors beenden

  • Hallo,

    Ich würde gerne ein Programm schreiben welches überprüft ob der Monitor (durch Windows) abgeschaltet wurde.
    Wenn ja sollen ein paar Programme beendet werden.
    Wenn der Moitor wieder aktiviert wird (z.B. druch drücken einer Maustaste) sollen die Programme wieder gestartet werden.
    I
    Das Programm an sich bekomme ich hin, ich weiß nur nicht wie ich überprüfen kann ob der Monitir an/ oder aus ist, hat jemand von euch ne Idee?

    Mein Betriebssystem: Win 8.1 pro


    Hintergrund ist dass mein Rechner auch als Homeserver genutzt wird (24h), und ich die Programme (in der Taskbar) welche ich nur wärend ich vor dem Pc sitze benötigeauch nur dann laufen, um Ressourcen zu sparen.

    Gruß,

  • Hallo Harald,

    -------------------------------------------------------------------
    Wenn du C++ verstehst, hilft dir das eventuell weiter:

    http://cboard.cprogramming.com/windows-progra…html#post755545

    Solltest du es nicht verstehen, bleibt dir wohl nur der harte Weg über IO-Port-Sniffing, um die entsprechende On/Off-Message zu bekommen. Zum Testen kannst du beispielsweise diese Funktion verwenden, mit der du deinen Monitor gezielt abschalten kannst:

    http://www.autoitscript.com/forum/topic/57…-onoff-example/
    -------------------------------------------------------------------

    Viel Glück.
    Einexage

    Es gibt Tage, da trete ich nicht ins Fettnäpfchen. Ich falle in die Friteuse.

  • Spoiler anzeigen
    [autoit]


    Global Const $WM_POWERBROADCAST = 0x0218
    Global Const $PBT_POWERSETTINGCHANGE = 0x8013

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $WM_SYSCOMMAND = 0x0112
    Global Const $SC_MONITORPOWER = 0xF170
    Global Const $MONITOR_ON = -1
    Global Const $MONITOR_OFF = 2
    Global Const $MONITOR_STANDBY = 1

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $tagGUID = "struct; ulong Data1;ushort Data2;ushort Data3;byte Data4[8]; endstruct"
    Global Const $tagPOWERBROADCAST_SETTING = $tagGUID & ";DWORD DataLength;DWORD Data;"

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0
    Global Const $DEVICE_NOTIFY_SERVICE_HANDLE = 1

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $GUID_CONSOLE_DISPLAY_STATE = "{6fe69556-704a-47a0-8f24-c28d936fda47}" ; Win8
    Global Const $GUID_MONITOR_POWER_ON = "{02731015-4510-4526-99e6-e5a17ebd1aea}" ; Vista and Win7

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui = GUICreate("Gui for registering Windows Message", 600, 200)
    GUIRegisterMsg($WM_POWERBROADCAST, "_PowerSettingNotification")
    Global $nBtnSleep = GUICtrlCreateButton("Hey monitors, please sleep!", 50, 50, 500, 100)
    GUICtrlSetFont(-1, 25)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hNotify

    [/autoit] [autoit][/autoit] [autoit]

    If @OSBuild < 9000 Then
    $hNotify = _RegisterPowerSettingNotification($hGui, $GUID_MONITOR_POWER_ON)
    Else
    $hNotify = _RegisterPowerSettingNotification($hGui, $GUID_CONSOLE_DISPLAY_STATE)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    Global $iMsg
    Do
    $iMsg = GUIGetMsg()
    If $iMsg = $nBtnSleep Then DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hGui, 'int', $WM_SYSCOMMAND, 'int', $SC_MONITORPOWER, 'int', $MONITOR_OFF)
    Until $iMsg = -3

    [/autoit] [autoit][/autoit] [autoit]

    _UnregisterPowerSettingNotification($hNotify)

    [/autoit] [autoit][/autoit] [autoit]

    Func _PowerSettingNotification($hWndGUI, $MsgID, $wParam, $lParam)
    Local $tSetting, $iSetting
    If $wParam = $PBT_POWERSETTINGCHANGE Then
    $tSetting = DllStructCreate($tagPOWERBROADCAST_SETTING, $lParam)
    $iSetting = DllStructGetData($tSetting, "Data")
    Switch $iSetting
    Case 2 ;The display is dimmed --> Win8 and above
    ConsoleWrite("The display is dimmed now" & @CRLF)
    Case 1 ;The monitor in on
    ConsoleWrite("The display is on now" & @CRLF)
    Case 0 ;The monitor in off
    ConsoleWrite("The display is off now" & @CRLF)
    EndSwitch
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _RegisterPowerSettingNotification($hGui, $GUID)
    Local $tGuid = DllStructCreate($tagGUID)
    DllCall('ole32.dll', 'uint', 'CLSIDFromString', 'wstr', $GUID, 'struct*', $tGUID)
    Local $aRet = DllCall("user32.dll", "handle", "RegisterPowerSettingNotification", "handle", $hGui, "struct*", $tGUID, "DWORD", $DEVICE_NOTIFY_WINDOW_HANDLE)
    If @error Or $aRet[0] = 0 Then Return SetError(1, @error, 0)
    Return $aRet[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _UnregisterPowerSettingNotification($hNotify)
    Local $aRet = DllCall("user32.dll", "BOOL", "UnregisterPowerSettingNotification", "handle", $hNotify)
    If @error Or $aRet[0] = 0 Then Return SetError(1, @error, 0)
    Return $aRet[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit]

    Edit: Beispiel verschönert

  • Hallo,
    ich konnte mich leider erst jezt wieder mit meinem Programm befassen.
    Vielen dank für eure Hilfe.
    ( @funkey und Einexage mit den Beispielen muss ich mich mal an einem freien Abend beschäftigen, hab erst vor kurzem mit dem Programmieren angefangen ;) )

    Ich hab es jetzt mal relativ einfach mit "GetIdleTime" umgesetzt.

    funktioniert soweit ganz gut ( für Verbesserungsvorschläge bin ich natürlich immer offen :) ).
    Nur startet das Programm "Pushbullet" nicht versteckt im Infobrechich (bzw. Systemtray oder wie man das auch immer nennt) sondern öffnet jedemal das Anwendungsfenster. Gibt es eine Möglichkeit das Programm gleich versteckt im Infobereich zu starten ober nach dem Start zu minimieren?


    Was auch noch relativ unschön ist, dass sich der Infobereich nach dem Beenden der Programme nicht automatisch aktualisiert und die Widgets noch angezeigt werden bis ich mit der Maus darüber fahre.[Blockierte Grafik: http://www.bilderbob.de/galerie/142064369020117/2e3eeaecf41e3597542fd186d439e1d4.jpg][Blockierte Grafik: http://www.bilderbob.de/galerie/142064369020117/2e3eeaecf41e3597542fd186d439e1d4.jpg]
    Ist des möglich den Infobereich mit Autoit zu aktualisieren?


    Gruß,

    4 Mal editiert, zuletzt von Harald654 (7. Januar 2015 um 16:31)

    • Offizieller Beitrag

    Die Icons aus dem Tray werden nicht entfernt, weil Du Deine Programme mittels ProcessClose "abschießt". Du musst WinClose einsetzen, damit die Programme "normal" beendet werden.
    Ich habe mal ein kleines Script geschrieben:

    Spoiler anzeigen
    [autoit]


    #include <Timers.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $aPrograms[3] = ['mspaint.exe', 'calc.exe', 'notepad.exe'] ; <- die zu startenden Programme
    Global $iSleepTime = 10000 ; <- Zeit in Millisekunden

    [/autoit] [autoit][/autoit] [autoit]

    Global $aPIDs[UBound($aPrograms)], $fStart = False, $fStop = False, $iIdleTime
    HotKeySet('{ESC}', '_End')

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(100)
    $iIdleTime = _Timer_GetIdleTime()
    ToolTip($iIdleTime)
    If Not $fStart And $iIdleTime > $iSleepTime Then
    $fStart = True
    $fStop = False
    _StopPrograms($aPrograms)
    EndIf
    If Not $fStop And $iIdleTime < $iSleepTime Then
    $fStop = True
    $fStart = False
    _StartPrograms($aPrograms)
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _End()
    _StopPrograms($aPrograms)
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _StartPrograms(ByRef $aPrograms)
    For $i = 0 To UBound($aPrograms) - 1
    $aPIDs[$i] = Run($aPrograms[$i])
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _StopPrograms(ByRef $aPrograms)
    Local $aWinList = WinList(), $iPID
    For $i = 0 To UBound($aPrograms) - 1
    For $j = 1 To $aWinList[0][0]
    $iPID = WinGetProcess($aWinList[$j][0])
    If $iPID = $aPIDs[$i] Then WinClose($aWinList[$j][0])
    Next
    Next
    EndFunc

    [/autoit]
  • Und nun komme ich. :rofl:

    Was ist, wenn ich den Monitor-2 ausschalte? Dann schließt sich gar nichts.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Danke für das Skript Oscar, das ist um einiges schöner wie meins :)

    Mit WinClose (bzw. Winkill) lassen Sich leider einige Programme im Infobereich nicht ändern :/
    Gibt es den noch ne alternative um die Proramme zu beenden wobei auch das Logo im Infobereich verschindet?


    Gruß,

  • Konkret ist das bei dem Denktopclient für Pushbullet so (ist ein Programm um Android-Benachrichtigungen auf dem PC anzuzeigen), dort kann ich mit WinClose nur die geöffnete Anwendung/Fenster schließen, aber nicht den Dienst im Infobereich (was aber eine Super lösung für mein anderes Problem ist das Pushbullet immer als Fenster Startet :) )

    Und ein Dienstprogramm für meine 3D Maus (3D Connection) lasst sich auch nicht mittels WinClose beenden (das mir aber auch nicht so wichtig)

    Die Programmname dürften ja die gleichen sein wie für ProcessClose? (die hab ich mir die einfach aus dem Tankmanager geholt)


    Gruß,