Problem mit Services.au3

  • Hallo zusammen,

    ich bin neu hier im Forum angemeldet, habe allerdings schon einige nützliche Threads und Skripte in der Vergangenheit gelesen.

    Da ich aber jetzt allein nicht mehr weiter komme benötige ich eure Hilfe.

    Ich habe für ein Selbstgeschriebenes Datensicherungsprogramm (auf Snapshot Basis) einen Dienst geschrieben, welcher die Sicherung zur jeweiligen Zeit am entsprechenden Tag anstößt.
    Ich weiss man hätte das auch über den Taskplaner machen können, aber ich wollte die Konfiguration komplett in meiner eigenen GUI abbilden.

    Der Dienst den ich dazu geschrieben habe ist auf Basis der "services.au3" die hier im Forum auch schon vorgestellt wurde.
    Der Dienst funktioniert im Prinzip auch so wie er sollte (installieren / starten / stoppen / deinstallieren) und er startet auch die Sicherung zur angegebenen Zeit.

    Das Problem was ich habe ist, das der Dienst manchmal mit 100% CPU Last (oder 50% bei Dualcore etc.) läuft und der gesamte Rechner lahm wird.

    Ich vermute ich mache bei Initialisieren des Dienstes noch etwas falsch...

    Ich werde jetzt erstmal nur die _svc_main() Funktion posten, da der gesamte Code von mir (ausser Installation und Deinstallation) in dieser Funktion steht.
    Solltet ihr noch mehr Quelltext brauchen, dann kann ich den sicherlich noch nachreichen.


    Ich hoffe ich habe nicht allzuviel falsch gemacht :)

    Spoiler anzeigen
    [autoit]

    Func _Svc_Main()
    main_init()
    local $config= @ScriptDir & "\config.ini"
    local $runsnap
    logPrint("main start")
    logPrint("main loop. evnt=" & _WinAPI_WaitForSingleObject($service_stop_event, 0))

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

    While $gServiceStateRunning
    if FileExists($config) Then
    local $Szeit=IniRead($config,"Client","Sicherungszeit","")
    local $Styp=IniRead($config,"Client","Intervalltyp","")
    local $STage=IniRead($config,"Client","Wochentage","")
    local $dayarray , $aktweekday
    local $mo, $di, $mi, $do, $fr, $sa, $so

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

    $szeit=StringSplit($szeit,":",2)
    $szeit[1]=Stringleft($szeit[1],2)

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

    if NOT StringInStr($STage,",") = 0 Then
    $dayarray = StringSplit($STage,",",2)
    for $i=0 to UBound($dayarray)-1 step 1
    Select
    case $dayarray[$i] = 1
    $mo = 2
    case $dayarray[$i] = 2
    $di = 3
    case $dayarray[$i] = 3
    $mi = 4
    case $dayarray[$i] = 4
    $do = 5
    case $dayarray[$i] = 5
    $fr = 6
    case $dayarray[$i] = 6
    $sa = 7
    case $dayarray[$i] = 7
    $so = 1
    EndSelect
    Next
    Else
    Select
    case $STage = 1
    $mo = 2
    case $STage = 2
    $di = 3
    case $STage = 3
    $mi = 4
    case $STage = 4
    $do = 5
    case $STage = 5
    $fr = 6
    case $STage = 6
    $sa = 7
    case $STage = 7
    $so = 1
    EndSelect
    EndIf

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

    Select
    case $Styp="Manuell" or $Styp="Wöchentlich"
    if @WDAY=$mo or @WDAY=$di or @WDAY=$mi or @WDAY=$do or @WDAY=$fr or @WDAY=$sa or @WDAY=$so then
    if @HOUR = $szeit[0] Then
    if @min = $szeit[1] Then
    $runsnap=run(@ScriptDir & "\Komplettsicherung.exe start",@ScriptDir)
    logPrint("main Snapshot " & $runsnap)
    sleep(60000)
    EndIf
    EndIf
    EndIf
    Sleep(10000)
    case $Styp="Monatlich"
    if @MDAY>0 AND @mday<8 Then
    $aktweekday = _DateToDayOfWeek(@year, @MON, @mday)
    if $aktweekday=$mo or $aktweekday=$di or $aktweekday=$mi or $aktweekday=$do or $aktweekday=$fr or $aktweekday=$sa or $aktweekday=$so then
    if @HOUR = $szeit[0] Then
    if @min = $szeit[1] Then
    $runsnap=run(@ScriptDir & "\Komplettsicherung.exe start",@ScriptDir)
    logPrint("main Snapshot " & $runsnap)
    sleep(60000)
    EndIf
    EndIf
    EndIf
    EndIf
    Sleep(10000)
    EndSelect
    EndIf
    WEnd
    logPrint("main outer. evnt=" & _WinAPI_WaitForSingleObject($service_stop_event, 0))

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

    _Service_Cleanup()
    logPrint("main stopped.")
    EndFunc ;==>main

    [/autoit]

    Grüße
    Daniel

  • Nein die Auslastung kommt direkt nach dem starten des Dienstes.

    Und ich kann es nicht zu 100% sicher sagen, aber oftmals auch dann, wenn in der Ini-Datei die ausgelesen wird keine Werte stehen...


    Ist denn zumindest der Ansatz meiner Funktion korrekt?


    Gruß
    Daniel

  • Hi!


    Die funktion ist ein wenig überfüllt da kann man eine mänge kürzen, das ist daber nicht das anligen, ich würde vorschlagen das ganze Sktipt zu posten
    Und ein Error Handling für die Ini wehr sehr vorteilhaft.


    Lg Kleiner

  • Spoiler anzeigen
    [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $MainLog = @ScriptDir & "\Snapshot_Service.log"
    Global $sServiceName = "Snapshot"

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

    #include "Services.au3"
    #Include <Date.au3>
    #include <Timers.au3> ; i used it for timers func

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

    logPrint("script started")
    If $cmdline[0] > 0 Then
    Switch $cmdline[1]
    Case "install", "-i", "/i"
    InstallService()
    Case "remove", "-u", "/u", "uninstall"
    RemoveService()
    case "start"
    _service_start($sServiceName)
    case "stop"
    _service_stop($sServiceName)
    case "delete"
    _service_delete($sServiceName)
    Case Else
    ConsoleWrite(" - - - Help - - - " & @CRLF)
    ConsoleWrite("params : " & @CRLF)
    ConsoleWrite(" -i : install service" & @CRLF)
    ConsoleWrite(" -u : remove service" & @CRLF)
    ConsoleWrite(" - - - - - - - - " & @CRLF)
    Exit
    ;start service.
    EndSwitch
    EndIf
    _Service_init($sServiceName)

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

    Func main_init()
    logPrint("main_init. Stop event=" & $service_stop_event)
    EndFunc ;==>main_init

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

    Func _Svc_Main()
    main_init()
    local $config= @ScriptDir & "\config.ini"
    local $runsnap
    logPrint("main start")
    logPrint("main loop. evnt=" & _WinAPI_WaitForSingleObject($service_stop_event, 0))

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

    While $gServiceStateRunning
    if FileExists($config) Then
    local $Szeit=IniRead($config,"Client","Sicherungszeit","")
    local $Styp=IniRead($config,"Client","Intervalltyp","")
    local $STage=IniRead($config,"Client","Wochentage","")
    local $dayarray , $aktweekday
    local $mo, $di, $mi, $do, $fr, $sa, $so

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

    $szeit=StringSplit($szeit,":",2)
    $szeit[1]=Stringleft($szeit[1],2)

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

    if NOT StringInStr($STage,",") = 0 Then
    $dayarray = StringSplit($STage,",",2)
    for $i=0 to UBound($dayarray)-1 step 1
    Select
    case $dayarray[$i] = 1
    $mo = 2
    case $dayarray[$i] = 2
    $di = 3
    case $dayarray[$i] = 3
    $mi = 4
    case $dayarray[$i] = 4
    $do = 5
    case $dayarray[$i] = 5
    $fr = 6
    case $dayarray[$i] = 6
    $sa = 7
    case $dayarray[$i] = 7
    $so = 1
    EndSelect
    Next
    Else
    Select
    case $STage = 1
    $mo = 2
    case $STage = 2
    $di = 3
    case $STage = 3
    $mi = 4
    case $STage = 4
    $do = 5
    case $STage = 5
    $fr = 6
    case $STage = 6
    $sa = 7
    case $STage = 7
    $so = 1
    EndSelect
    EndIf

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

    Select
    case $Styp="Manuell" or $Styp="Wöchentlich"
    if @WDAY=$mo or @WDAY=$di or @WDAY=$mi or @WDAY=$do or @WDAY=$fr or @WDAY=$sa or @WDAY=$so then
    if @HOUR = $szeit[0] Then
    if @min = $szeit[1] Then
    $runsnap=run(@ScriptDir & "\Komplettsicherung.exe start",@ScriptDir)
    logPrint("main Snapshot " & $runsnap)
    sleep(60000)
    EndIf
    EndIf
    EndIf
    Sleep(10000)
    case $Styp="Monatlich"
    if @MDAY>0 AND @mday<8 Then
    $aktweekday = _DateToDayOfWeek(@year, @MON, @mday)
    if $aktweekday=$mo or $aktweekday=$di or $aktweekday=$mi or $aktweekday=$do or $aktweekday=$fr or $aktweekday=$sa or $aktweekday=$so then
    if @HOUR = $szeit[0] Then
    if @min = $szeit[1] Then
    $runsnap=run(@ScriptDir & "\Komplettsicherung.exe start",@ScriptDir)
    logPrint("main Snapshot " & $runsnap)
    sleep(60000)
    EndIf
    EndIf
    EndIf
    EndIf
    Sleep(10000)
    EndSelect
    EndIf
    WEnd
    logPrint("main outer. evnt=" & _WinAPI_WaitForSingleObject($service_stop_event, 0))

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

    _Service_Cleanup()
    logPrint("main stopped.")
    EndFunc ;==>main

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

    Func logPrint($text, $nolog = 0)
    If $nolog Then
    MsgBox(0, "MyService", $text, 1)
    Else
    If Not FileExists($MainLog) Then FileWriteLine($MainLog, "Log created: " & @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC)
    FileWriteLine($MainLog, @YEAR & @MON & @MDAY & " " & @HOUR & @MIN & @SEC & " [" & @AutoItPID & "] >> " & $text)
    EndIf
    Return 0
    EndFunc ;==>logPrint

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

    Func InstallService()
    logPrint("InstallService(): Installing service, please wait")
    _Service_Create($sServiceName, "Snapshot", $SERVICE_WIN32_OWN_PROCESS, $SERVICE_AUTO_START, $SERVICE_ERROR_IGNORE,'"' & @ScriptFullPath & '"')
    If @error Then
    logPrint("InstallService(): Problem installing service, Error number is " & @error & @CRLF & " message : " & _WinAPI_GetLastErrorMessage())
    Else
    RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\" & $sServiceName, "Description", "REG_SZ", "Snapshot Datensicherung")
    logPrint("InstallService(): Installation of service successful")
    EndIf
    Exit
    EndFunc ;==>InstallService

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

    Func RemoveService()
    _Service_Stop($sServiceName)
    _Service_Delete($sServiceName)
    If Not @error Then logPrint("RemoveService(): service removed successfully" & @CRLF)
    Exit
    EndFunc ;==>RemoveService

    [/autoit]

    Das ist der komplette Code für den Dienst.

    Du meinst also es könnte sein das er ein Fehler beim lesen der Ini hat und sich das Script dadurch "aufhängt" und die Auslastung nach oben treibt?
    Ich werde das mal testen und sobald ich dazu komme eine Fehlerprüfung auf die Ini-Datei selbst und auf alle ausgelesenen Werte durchführen... daran hab ich jetzt noch gar nicht gedacht.


    Gruß
    Daniel