ProcessWatcher

  • Hallo zusammen,

    um gleich zur Sache zu kommen.

    Ich erstelle (versuche) gerade ein Script zu erstellen das auf einige Prozesse achten soll die in einer .ini gelistet sind.

    Wenn jetzt nun einer der Prozesse aus der .ini gestartet wird, soll dieser die Priortät "Hoch" bekommen.

    Hier mal die .ini

    Spoiler anzeigen

    hier der Beginn

    Spoiler anzeigen
    [autoit]

    $var = IniRead($ini, "Process", "001","")

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

    If ProcessExists($var) Then
    ProcessSetPriority($var, 0)
    EndIf

    [/autoit]

    Wie stelle ich es an, das er "alle" Prozesse die in der .ini eingetragen sind überwacht und wenn der Prozess startet, auch gleich dessen Priorität ändert?


    Fragt nicht nach dem Sinn dieses Scripts es soll lediglich zu meinen eigenen Testzwecken verwendet werden. Aber genau deshalb benötige ich etwas Hilfestellung dabei.

    LG

    Schnuecks

  • [autoit]

    For $i = 1 To 5
    $var = IniRead($ini, "Process", $i,"")

    If ProcessExists($var) Then
    ProcessSetPriority($var, 0)
    EndIf
    Next

    [/autoit]


    Ungetestet nur hier reingeschrieben. Aber so in Etwa?

  • Habe es auf meine weise gelöst nur weis ich nicht ob das jetzt eine gute ist. Wenn ich das Script jetzt starte hat die CPU ne Auslastung von um die 40% das will ich natürlich nicht so haben. Ich zeige Euch hier nochmal was ich bis jetzt gemacht habe.

    1. die INI

    Spoiler anzeigen

    2. die variablen.au3

    Spoiler anzeigen
    [autoit]

    ;Variablen.au3
    $ini = "ProcessNames.ini"

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

    $var01 = IniRead($ini, "Process", "001","")
    $var02 = IniRead($ini, "Process", "002","")
    $var03 = IniRead($ini, "Process", "003","")
    $var04 = IniRead($ini, "Process", "004","")
    $var05 = IniRead($ini, "Process", "005","")
    $var06 = IniRead($ini, "Process", "006","")
    $var07 = IniRead($ini, "Process", "007","")
    $var08 = IniRead($ini, "Process", "008","")
    $var09 = IniRead($ini, "Process", "009","")
    $var10 = IniRead($ini, "Process", "010","")
    $var11 = IniRead($ini, "Process", "011","")
    $var12 = IniRead($ini, "Process", "012","")
    $var13 = IniRead($ini, "Process", "013","")
    $var14 = IniRead($ini, "Process", "014","")
    $var15 = IniRead($ini, "Process", "015","")
    $var16 = IniRead($ini, "Process", "016","")
    $var17 = IniRead($ini, "Process", "017","")
    $var18 = IniRead($ini, "Process", "018","")
    $var19 = IniRead($ini, "Process", "019","")
    $var20 = IniRead($ini, "Process", "020","")

    [/autoit]

    3. das Script selbst

    Spoiler anzeigen
    [autoit]

    #cs ----------------------------------------------------------------------------

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

    Author: Schnuecks

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

    Script Function:
    ProcessWatcher script.

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

    #ce ----------------------------------------------------------------------------

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

    #include "variablen.au3"

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

    ;Endlosschleife
    While -1

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

    ;Process 1
    If ProcessExists($var01) Then
    ProcessSetPriority($var01, 0)
    EndIf

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

    ;Process 2
    If ProcessExists($var02) Then
    ProcessSetPriority($var02, 0)
    EndIf

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

    ;Process 3
    If ProcessExists($var03) Then
    ProcessSetPriority($var03, 0)
    EndIf

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

    ;Process 4
    If ProcessExists($var04) Then
    ProcessSetPriority($var04, 0)
    EndIf

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

    ;Process 5
    If ProcessExists($var05) Then
    ProcessSetPriority($var05, 0)
    EndIf

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

    ;Process 6
    If ProcessExists($var06) Then
    ProcessSetPriority($var06, 0)
    EndIf

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

    ;Process 7
    If ProcessExists($var07) Then
    ProcessSetPriority($var07, 0)
    EndIf

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

    ;Process 8
    If ProcessExists($var08) Then
    ProcessSetPriority($var08, 0)
    EndIf

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

    ;Process 9
    If ProcessExists($var09) Then
    ProcessSetPriority($var09, 0)
    EndIf

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

    ;Process 10
    If ProcessExists($var10) Then
    ProcessSetPriority($var10, 0)
    EndIf

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

    ;Process 11
    If ProcessExists($var11) Then
    ProcessSetPriority($var11, 0)
    EndIf

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

    ;Process 12
    If ProcessExists($var12) Then
    ProcessSetPriority($var12, 0)
    EndIf

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

    ;Process 13
    If ProcessExists($var13) Then
    ProcessSetPriority($var13, 0)
    EndIf

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

    ;Process 14
    If ProcessExists($var14) Then
    ProcessSetPriority($var14, 0)
    EndIf

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

    ;Process 15
    If ProcessExists($var15) Then
    ProcessSetPriority($var15, 0)
    EndIf

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

    ;Process 16
    If ProcessExists($var16) Then
    ProcessSetPriority($var16, 0)
    EndIf

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

    ;Process 17
    If ProcessExists($var17) Then
    ProcessSetPriority($var16, 0)
    EndIf

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

    ;Process 18
    If ProcessExists($var18) Then
    ProcessSetPriority($var18, 0)
    EndIf

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

    ;Process 19
    If ProcessExists($var19) Then
    ProcessSetPriority($var19, 0)
    EndIf

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

    ;Process 20
    If ProcessExists($var20) Then
    ProcessSetPriority($var20, 0)
    EndIf

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

    WEnd

    [/autoit]


    Bitte seit nicht so streng mit mir ^^ ich kanns halt noch nicht besser ^^


    Könnts ihr mir noch bissl weiterhelfen, wie ich die CPU Last reduzieren kann.
    Wenn ich dann in der .ini etwas ändere muss ja das Script neu gestartet werden, das müsste doch irgendwie machbar sein.

    LG

    Schnuecks

    Einmal editiert, zuletzt von Schnuecks (29. Juli 2007 um 17:02)

  • [autoit]

    While 1
    For $i = 1 To 5
    $var = IniRead($ini, "Process", $i,"")

    If ProcessExists($var) Then
    ProcessSetPriority($var, 0)
    EndIf
    Next
    Sleep(1000) ; macht die CPU-Auslastung runter!
    WEnd

    [/autoit]
    • Offizieller Beitrag

    Die INI nur einmal außerhalb der Schleife lesen:

    [autoit]

    $ini = "ProcessNames.ini"
    $arProcess = IniReadSection($ini, "Process")
    HotKeySet("!e", "ende") ; HotKey Alt+e zum Beenden
    While 1
    For $i = 1 To $arProcess[0][0]
    If ProcessExists($arProcess[$i][1]) Then
    ProcessSetPriority($arProcess[$i][1], 0)
    EndIf
    Next
    Sleep(1000) ; Überprüfungs-Intervall, hier 1 Sekunde
    WEnd

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

    Func ende()
    Exit
    EndFunc

    [/autoit]
  • Vielen Dank schonmal an alle.

    Die Lösung von BugFix hat mir sehr geholfen. Ich musste lediglich in der .ini noch die Wert ändern z. B. 001 --> 1 dann gings.

    Falls ich noch Fragen habe werde ich mich nicht schäuen sie Euch zu stellen XD


    LG

    Schnuecks

    • Offizieller Beitrag

    Auch für dich: Bitte keine Doppelposts, editieren. ;)

    Wenn du während des laufenden Programms die INI änderst, mußt du schon das Programm erneut starten, damit alle Einträge berücksichtigt werden.

    Man könnt sicher eine Konstruktion bauen, die auch das ermöglicht, aber ich halte das nicht für sinnvoll.

  • Ob sinnvoll oder nicht: Für die, die es interessiert hier mal die einfache Version zum INI-ändern während der Laufzeit:

    Spoiler anzeigen
    [autoit]

    Opt("MustDeclareVars", 1)
    HotKeySet("!e", "OnAutoItExit")

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

    Local Const $S_INIFILE = @ScriptDir & "\ProcessNames.ini"
    Local $a_iniindex = IniReadSection($S_INIFILE, "Process")
    Local $s_orginitime = FileGetTime($S_INIFILE, 0, 1)
    Local $s_curinitime = ""

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

    If @error <> 0 Then
    Exit (1)
    EndIf

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

    While 1
    For $i = 1 To $a_iniindex[0][0] Step 1
    If $a_iniindex[$i][1] <> "" Then
    If ProcessExists($a_iniindex[$i][1]) <> 0 Then
    ProcessSetPriority($a_iniindex[$i][1], 0)
    EndIf
    EndIf
    Sleep(500)
    Next

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

    $s_curinitime = FileGetTime($S_INIFILE, 0, 1)
    If $s_curinitime <> $s_orginitime Then
    $a_iniindex = IniReadSection($S_INIFILE, "Process")
    $s_orginitime = $s_curinitime
    EndIf
    WEnd

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

    Func OnAutoItExit()
    If @HotKeyPressed <> "" Then
    Exit (0)
    EndIf

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

    Exit (@exitCode)
    EndFunc ;==>OnAutoItExit

    [/autoit]
  • Danke, werde ich mir mal anschauen und evtl. einbauen.

    Wie bekomme ich im Tray Icon das Menü Pause weg, wenn ich das Exit behalten möchte.

    Ich hatte mal etwas mit probiert das hat mir zwar ein Menü angezeigt aber das eigentlich Script dann nicht mehr berücksichtigt.

    Wo liegt der Fehler?

    Spoiler anzeigen
    [autoit]

    #Include <Constants.au3>
    #NoTrayIcon

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

    HotKeySet("!q", "ende") ; HotKey Alt+e zum Beenden
    Func ende()
    Exit
    EndFunc

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

    Opt("TrayMenuMode",1) ; Default tray menu items (Script Paused/Exit) will not be shown.

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

    $aboutitem = TrayCreateItem("About")
    TrayCreateItem("")
    $exititem = TrayCreateItem("Exit")

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

    TraySetState()

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

    While 1
    $msg = TrayGetMsg()
    Select
    Case $msg = 0
    ContinueLoop
    Case $msg = $aboutitem
    Msgbox(64,"About:","Zum Testen")
    Case $msg = $exititem
    ExitLoop
    EndSelect
    WEnd

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

    Exit
    ;Script
    $ini = "ProcessNames.ini"
    $arProcess = IniReadSection($ini, "Process")

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

    While 1
    For $i = 1 To $arProcess[0][0]
    If ProcessExists($arProcess[$i][1]) Then
    ProcessSetPriority($arProcess[$i][1], 0)
    EndIf
    Next
    Sleep(1000) ; Überprüfungs-Intervall, hier 1 Sekunde
    WEnd

    [/autoit]

    LG

    Schnuecks

    2 Mal editiert, zuletzt von Schnuecks (29. Juli 2007 um 19:17)

  • Der fehler liegt an den 2 While schleifen die musst du zu einer machen dann klappts auch.

  • Das liegt daran, dass Du ja niemals aus Deinem Tray-Loop heraus kommst. Du musst alles in eine Schleife packen:

    Spoiler anzeigen
    [autoit]

    Opt("MustDeclareVars", 1)
    Opt("TrayMenuMode", 1)
    HotKeySet("!e", "OnAutoItExit")

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

    Local Const $S_INIFILE = @ScriptDir & "\ProcessNames.ini"
    Local $h_abouttitem = -1
    Local $h_exitmitem = -1
    Local $i_msg = -1
    Local $s_orginitime = FileGetTime($S_INIFILE, 0, 1)
    Local $s_curinitime = ""

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

    Local $a_iniindex = IniReadSection($S_INIFILE, "Process")
    If @error <> 0 Then
    Exit (1)
    EndIf

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

    $h_abouttitem = TrayCreateItem("About")
    TrayCreateItem("")
    $h_exitmitem = TrayCreateItem("Exit")
    TraySetClick(8)

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

    While 1
    $i_msg = TrayGetMsg()
    Select
    Case $i_msg == $h_abouttitem
    MsgBox(64, "About:", "Zum Testen")
    Case $i_msg == $h_exitmitem
    ExitLoop 1
    EndSelect

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

    For $i = 1 To $a_iniindex[0][0] Step 1
    If $a_iniindex[$i][1] <> "" Then
    If ProcessExists($a_iniindex[$i][1]) <> 0 Then
    ProcessSetPriority($a_iniindex[$i][1], 0)
    EndIf
    EndIf
    Next

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

    $s_curinitime = FileGetTime($S_INIFILE, 0, 1)
    If $s_curinitime <> $s_orginitime Then
    $a_iniindex = IniReadSection($S_INIFILE, "Process")
    $s_orginitime = $s_curinitime
    EndIf
    WEnd
    Exit (0)

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

    Func OnAutoItExit()
    If @HotKeyPressed <> "" Then
    Exit (0)
    EndIf

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

    Exit (@exitCode)
    EndFunc ;==>OnAutoItExit

    [/autoit]


    Das Problem dabei ist dann aber, dass Du entweder auf das Sleep verzichtest (siehe oben!) oder aber mittels AdlibEnable() die Funktion zum Überprüfen der Prozesse alle paar Sekunden aufrufst:

    Spoiler anzeigen
    [autoit]

    Opt("MustDeclareVars", 1)
    Opt("TrayMenuMode", 1)
    HotKeySet("!e", "OnAutoItExit")

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

    Local Const $S_INIFILE = @ScriptDir & "\ProcessNames.ini"
    Global $a_iniindex = IniReadSection($S_INIFILE, "Process")
    If @error <> 0 Then
    Exit (1)
    EndIf

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

    Local $h_abouttitem = -1
    Local $h_exitmitem = -1
    Local $i_msg = -1
    Local $s_orginitime = FileGetTime($S_INIFILE, 0, 1)
    Local $s_curinitime = ""

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

    $h_abouttitem = TrayCreateItem("About")
    TrayCreateItem("")
    $h_exitmitem = TrayCreateItem("Exit")
    TraySetClick(8)
    AdlibEnable("CheckProcesses", 1000)

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

    While 1
    $i_msg = TrayGetMsg()
    Select
    Case $i_msg == $h_abouttitem
    MsgBox(64, "About:", "Zum Testen")
    Case $i_msg == $h_exitmitem
    ExitLoop 1
    EndSelect

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

    $s_curinitime = FileGetTime($S_INIFILE, 0, 1)
    If $s_curinitime <> $s_orginitime Then
    $a_iniindex = IniReadSection($S_INIFILE, "Process")
    $s_orginitime = $s_curinitime
    EndIf
    WEnd
    Exit (0)

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

    Func CheckProcesses()
    For $i = 1 To $a_iniindex[0][0] Step 1
    If $a_iniindex[$i][1] <> "" Then
    If ProcessExists($a_iniindex[$i][1]) <> 0 Then
    ProcessSetPriority($a_iniindex[$i][1], 0)
    EndIf
    EndIf
    Next
    EndFunc

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

    Func OnAutoItExit()
    AdlibDisable()
    If @HotKeyPressed <> "" Then
    Exit (0)
    EndIf

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

    Exit (@exitCode)
    EndFunc ;==>OnAutoItExit

    [/autoit]


    Dies wird durch das Sleep() in der While-Schleife verursacht. Ich würde die zweite Variante verwenden und den Adlib-Intervall ruhig auf 10000 oder mehr setzen. (So zeitkritisch kann das Ganze doch nicht sein...)

  • Das funktioniert jetzt wunderbar.

    Eine kleine Idee zur Vervollständigung hätte ich noch.

    Ich dachte da an folgendes:

    [autoit]

    Local $prio = InputBox("Priorität eingeben", "0 - Niedrig" & @crlf & "1 - Niedriger als normal" & @crlf & "2 - Normal" & @crlf & "3 - Höher als Normal" & @crlf & "4 - Hoch" & @crlf & "5 - Echtzeit - Vorsicht", "2")

    [/autoit]

    um dann weiter unten im Script

    [autoit]

    For $i = 1 To $a_iniindex[0][0] Step 1
    If $a_iniindex[$i][1] <> "" Then
    If ProcessExists($a_iniindex[$i][1]) <> 0 Then
    ProcessSetPriority($a_iniindex[$i][1], $prio)
    EndIf
    EndIf
    Next

    [/autoit]

    Ich möchte das die Box erscheint und erstens nur der Wert zwischen 0 und 5 eingegeben werden kann und wenn man den Cancel Button der Box drückt das Script beendet wird.


    Ich bin von Euch begeistert ^^

    Einmal editiert, zuletzt von Schnuecks (29. Juli 2007 um 21:17)

    • Offizieller Beitrag

    Tipp:
    Nimm nicht die Standard-Input Box, sondern mach eine kleine GUI mit Inputfeld. Dort kannst du als Style festlegen: $ES_NUMBER
    Das läßt nur numerische Eingaben zu. Wenn dabei der Bereich überschritten/unterschritten wird, blendest du diese GUI einfach wieder zur Korrektur ein.

  • Ich würde einen anderen Ansatz wählen. Zunächst einmal würde ich die INI-Datei folgendermaßen ändern:

    Processes.ini

    Spoiler anzeigen
    Code
    [ProcessPriority]
    totalcmd.exe = 0
    everest.exe = 1
    mplayerc.exe = 4
    iexplore.exe = 2
    firefox.exe = 5


    Nach ein paar Modifizierungen am Skript, lässt sich jetzt bereits im Vorfeld festlegen, welcher Prozess, welche Priorität bekommen soll. (Damit wird ein Benutzereingriff unnötig!):
    ProcessWatcher.au3

    Spoiler anzeigen
    [autoit]

    Opt("MustDeclareVars", 1)
    Opt("TrayMenuMode", 1)
    HotKeySet("!e", "OnAutoItExit")

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

    Local Const $S_INIFILE = @ScriptDir & "\Processes.ini"
    Global Const $S_INISECTION = "ProcessPriority"
    Global $a_iniindex = IniReadSection($S_INIFILE, $S_INISECTION)
    If @error <> 0 Then
    MsgBox(16, "ERROR", "The INI file may not exist or the section may not exist!")
    Exit (1)
    EndIf
    Global $s_orginitime = FileGetTime($S_INIFILE, 0, 1)

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

    Local $h_abouttitem = -1
    Local $h_exitmitem = -1
    Local $i_msg = -1

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

    $h_abouttitem = TrayCreateItem("About")
    TrayCreateItem("")
    $h_exitmitem = TrayCreateItem("Exit")
    TraySetClick(8)
    AdlibEnable("CheckProcesses", 30000)

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

    While 1
    $i_msg = TrayGetMsg()
    Select
    Case $i_msg == $h_abouttitem
    MsgBox(64, "About:", "Zum Testen")
    Case $i_msg == $h_exitmitem
    ExitLoop 1
    EndSelect
    WEnd
    Exit (0)

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

    Func CheckProcesses()
    Local $s_curinitime = FileGetTime($S_INIFILE, 0, 1)
    If $s_curinitime <> $s_orginitime Then
    $a_iniindex = IniReadSection($S_INIFILE, $S_INISECTION)
    $s_orginitime = $s_curinitime
    EndIf

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

    For $i = 1 To $a_iniindex[0][0] Step 1
    If $a_iniindex[$i][0] >= 0 And $a_iniindex[$i][0] <= 5 Then
    ;~ MsgBox(64, "Debug", "Process: " & $a_iniindex[$i][0] & @CR & "Priority: " & $a_iniindex[$i][1])
    If ProcessExists($a_iniindex[$i][0]) <> 0 Then
    ProcessSetPriority($a_iniindex[$i][0], $a_iniindex[$i][1])
    EndIf
    Else
    MsgBox(48, "WARNING", 'The priority flag for "' & $a_iniindex[$i][0] & '" is invalid!', 3)
    EndIf
    Next
    EndFunc ;==>CheckProcesses

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

    Func OnAutoItExit()
    AdlibDisable()
    If @HotKeyPressed <> "" Then
    Exit (0)
    EndIf

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

    Exit (@exitCode)
    EndFunc ;==>OnAutoItExit

    [/autoit]


    Habe zusätzlich noch das Überprüfen auf Änderungen an der INI-Datei mit in die AdLib-Funktion gepackt (machte zuvor keinen Sinn!) und zwei MsgBoxen im Falle von Fehlern hinzugefügt.

  • Das ist auch eine Möglichkeit die ich noch gar nicht bedacht habe und zudem um einiges komfortabler.

    Ich danke dir für Deine Mühe. Mir reichts es für heute und ich habe denke ich ne Menge gelernt.


    LG & Gut Nacht & vielen vielen Dank

    Schnuecks


    Edit:30.07.2007

    BTW: Das Thema kann als gelöst angesehen werden, meinerseits.

    Und nochmals vielen Dank, an alle

    Einmal editiert, zuletzt von Schnuecks (30. Juli 2007 um 15:46)