Jump to content
Sign in to follow this  
rudi

adlibenable("Function",1000): How exactly does it work?

Recommended Posts

rudi

Hi.

I wrote a small script, that has to copy a drive ALMOST up to it's rim.

For doing so, I use the "\i386\" folder of the current windows installation's "sourcepath" from registry. (I always copy over the Win-Setup source files to HDD for any installation I'm doing...)

With "Adlibenable("WipeOld",1000)" I wanted to check, if the free space on that drive drops below the size of the "\i386\" folder. If that should be fact, then delete the oldest one of the folders out there. Then the next copy step has enough free space to copy data over and over again, stressing the disks of a newly created host drive. (RAID)

To get the result code of robocopy, I use a runwait("robocopy sourcedir nextdestdir switches switches")

It looks like the adlibenabled function is never called? Maybe, adlibenable() is only executed, when

1.) the given timeframe is met AND...

2.) when the script is right now stepping from one line of code to the next one?

Or maybe my usage of Adlibdisable() / Adlibenable() is the reason, why it's never executed, because (possibly) every time I do so the timer will start from "0", so that the 1000 ms can never be reached?

Regards, Rudi.

#include <array.au3>
#include <date.au3>
#include <file.au3>

$ini = StringTrimRight(@ScriptFullPath, 3) & "ini"
If Not FileExists($ini) Then
    $initxt = ";Beispiel INI Datei für " & @ScriptName & @CRLF
    $initxt &= @CRLF
    $initxt &= "; Mit dem Parameter StopAt=YYYY/MM/DD hh:mm:ss kann festgelegt werden, wann der Platten-Last Test selbsttätig beendet werden soll" & @CRLF
    $initxt &= "; Fehlt der Parameter, oder ist er ungültig, dann läuft der Test immer weiter" & @CRLF
    $initxt &= @CRLF
    $initxt &= "[parameters]" & @CRLF
    $initxt &= ";Mit diesem Beispiel werden ab 08. Nov. 2009, 06:30 Uhr keine neuen Kopierjobs mehr gestartet" & @CRLF
    $initxt &= ";StopAt=2009/11/08 06:30:00" & @CRLF
    FileWrite($ini, $initxt)
EndIf

$StopAt = IniRead($ini, "Parameters", "StopAt", "never")

$Key = "hklm\software\microsoft\windows\currentversion\setup"
$val = "Sourcepath"
$Source = RegRead($Key, $val)
$ScrDir = @ScriptDir
If StringRight($ScrDir, 1) = "\" Then $ScrDir = StringTrimRight($ScrDir, 1) ; When started from a drive's root, @scriptdir will return a trailing "\" -> kick that one!



FileInstall("Robocopy.exe", $ScrDir & "\RobocopyXP.exe") ; Robocopy version 010. Version 026 from Robocopy-GUI does *NOT* return exit codes any more!!!

$Source = $Source & "\i386\"
$Source = StringReplace($Source, "\\", "\")
If StringLeft($Source, 1) = "\" Then $Source = "\" & $Source

If Not StringInStr(FileGetAttrib($Source), "d", 0) Then ; source directory doesn't exist
    MsgBox(48, "Fehler", "Der für diese Windows Installation in der Registry angegebene Source Path kann nicht gelesen werden: " & @LF & _
            $Source, 10)
    Exit
EndIf
$PlatzOrg = Ceiling(DirGetSize($Source) / 1024 / 1024)


If $StopAt = "Never" Then
    $LabelPrefix = "Belastungstest läuft unbegrenzt weiter. Zum Beenden dieses Scirpt stoppen (Symbol im Systray)" & @CRLF & @CRLF
Else
    $LabelPrefix = "Aus der INI gelesener Endzeitpunkt für den Belastungstest:" & @CRLF & $StopAt & @CRLF & @CRLF
EndIf
$LabelPrefix &= "Belastungstest für die Festplatten auf folgenden Pfad: " & @LF & $ScrDir & @LF & "Durchgang Nr.: "
$i = 1
$fatal = False


$Myi386 = $ScrDir & "\i386"
If Not DirCreate($Myi386) Then
    MsgBox(48, "Fehler", "Kann Verzeichnis '" & $Myi386 & "' nicht anlegen")
    $fatal = True
EndIf

$LogPath = $ScrDir & "\Log-Files\"

ConsoleWrite($ScrDir & @CRLF)

$Free = DriveSpaceFree($ScrDir)

$fatal = False

If $Free < $PlatzOrg * 3.5 Then
    MsgBox(48, "Zu wenig Platz", "Zu wenig Platz frei, um einen sinnvollen Belastungstest auf" & @CRLF & $ScrDir & @CRLF & "durchführen zu können!" & @CRLF & _
            "Frei  :    " & Ceiling($Free) & @CRLF & _
            "Benötigt :    " & Ceiling($PlatzOrg * 3.5), 20)
    $fatal = True
EndIf

If Not DirCreate($LogPath) Then
    MsgBox(48, "Ordner für LOG Dateien", "Der Ordner für die LOG Dateien kann nicht angelegt werden:" & @CRLF & $LogPath, 20)
    $fatal = True
EndIf

If $fatal Then
    MsgBox(64, "Fehler im Vorfeld", "Der Plattenbelastungstest konnte nicht ausgeführt werden, es sind Fehler im Vorfeld aufgetreten")
    Exit
EndIf


$w = 400
$h = 200
$MyWindow = GUICreate("Last auf Festplatten", $w, $h, @DesktopWidth - $w, 0)
$label = GUICtrlCreateLabel($LabelPrefix & $i, 20, 20, $w - 40, $h - 40)
GUISetState(@SW_SHOW)
WinSetOnTop($MyWindow, "", 1)




GUICtrlSetData($label, $LabelPrefix & "Estelle Grundkopie...")
RunWait("robocopyxp " & $Source & " " & $Myi386 & " /mir /r:0 /w:0 /reg /np /log:" & $LogPath & "\Robocopy-000000.log /tee")

$SammelLog=$LogPath & "Gesamt-Ergebnis.log"
if FileExists($SammelLog) Then FileMove($SammelLog,StringTrimRight($SammelLog,3)& "-" & FileGetTime($SammelLog,0,1) & ".BAK")
FileWriteLine($SammelLog,@crlf & @crlf & @crlf); 2 zeilen muss das Teil haben um bis Zeile 3 Einfügen zu können

AdlibEnable("WipeOld", 1000)
Dim $i = 0
Dim $DirArr[1] = [0]
While 1
    $i += 1 ; total number of runs
    $iStr = "00000" & $i
    $iStr = StringRight($iStr, 6)
    MakeNextDir()
    $Done = Round($i * $PlatzOrg / 1024, 2)
    If $Done > 100 Then
        $Done = Round($Done / 1024, 3) & " TB"
    Else
        $Done &= " GB"
    EndIf
    GUICtrlSetData($label, $LabelPrefix & $i & @CRLF & @CRLF & "Bisher kopiert: " & $Done)
    If $i = 1 Then ; create initial copy
        $result = RunWait("robocopyxp " & $Myi386 & " " & $DirArr[1] & " /mir /r:0 /w:0 /reg /np /log:" & $LogPath & "Robocopy-" & $iStr & ".log", "", @SW_HIDE)
                _FileWritetoLine($SammelLog, 1, "Plattentest begonnen: " & _NowCalc())
    Else
        $result = RunWait("robocopyxp " & $DirArr[2] & " " & $DirArr[1] & " /mir /r:0 /w:0 /reg /np /log:" & $LogPath & "\Robocopy-" & $iStr & ".log", "", @SW_HIDE)
    EndIf
    If $result = 1 Then ; robocopy exit code: only new files have been copied. (no fails, no extra files, ...)
        _FileWritetoLine($SammelLog,2, "   OK        : Durchgang " & $i & ", " & _NowCalc())
    Else
        _FileWritetoLine($SammelLog,2, "ExitCode = " & $result & " : Durchgang " & $i & ", " & _NowCalc())
    EndIf
    If $StopAt <> "never" Then
        If _DateDiff('s', $StopAt, _NowCalc()) > 1 Then
            _FileWriteToLine($SammelLog, 2, "Plattentest  beendet: " & _NowCalc() )
            _FileWriteToLine($SammelLog,3,"Kopiertes   Volumen: " & $Done)
            _FileWriteToLine($SammelLog, 4, "---------------------------------------------------------------------------------------------")
            run ("notepad " & $SammelLog)
            Exit
        EndIf
    EndIf
WEnd


Func MakeNextDir()
    AdlibDisable() ; here the wiping out of old data may *NOT* happen: it would mix up the array's content
    _ArrayAdd($DirArr, "") ; add "empty" element at the end of the array...
    $DirArr[0] = UBound($DirArr) - 1
    For $shift = $DirArr[0] To 2 Step -1 ; move all elements one element to array's end: So the oldest folder is at the end.
        $DirArr[$shift] = $DirArr[$shift - 1]
    Next
    $DirArr[1] = $ScrDir & "\SammelDir\Durchlauf-" & $iStr
    AdlibEnable("wipeold") ; from now on the "WipeOld" may be executed again: Array changes are done.
EndFunc   ;==>MakeNextDir


Func WipeOld()
    $Free = DriveSpaceFree($ScrDir)
    If $Free < $PlatzOrg * 1.3 Then ; Space is running short: delete oldest copy...
        DirRemove($DirArr[$DirArr[0]])
        _ArrayDelete($DirArr, $DirArr[0])
        $DirArr[0] = UBound($DirArr) - 1
    EndIf
EndFunc   ;==>WipeOld

Regards, Rudi.


Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites
Tvern

I can think of a few issues:

1. Robocopy doesn't shut down properly, making the script hang at "RunWait()"

2. AdlibEnable() takes 250ms to trigger by default. If your While loop takes less time than that it will disable and enable, resetting the timer again. (seems the more likely)

Share this post


Link to post
Share on other sites
martin

2. AdlibEnable() takes 250ms to trigger by default. If your While loop takes less time than that it will disable and enable, resetting the timer again. (seems the more likely)

Adlib is set to operate every 1000ms or every second, so the default 250ms is not being used. The while doesn't need to end because as soon as the while loop starts the function MakeNextDir() is called and the adlib function is disabled.That will happen a fraction of a millisecond after AdlibEnble I expect.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
rudi

Hi.

Adlib is set to operate every 1000ms or every second, so the default 250ms is not being used. The while doesn't need to end because as soon as the while loop starts the function MakeNextDir() is called and the adlib function is disabled.That will happen a fraction of a millisecond after AdlibEnble I expect.

MakeNextDir() does a

- adlibdisable()

- create new destination directory

- update the array

- adlibenable() again.

The following robocopy will take few minutes. (... in case there is enough free space. Otherwise it will return immediately with an error)

It looks to me as if during the external program robocopy.exe is run, the autoit script itself is "sleeping", waiting for the "runwait('robocopy....')" to end, without executing the adlibenabled function every second?

I've worked around this issue by starting a 2nd script watching the free space and doing the cleanup, but I'm hoping I'm using adlibenable() not correctly yet, so that I could do so from *ONE* script.

Regards, Rudi


Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites
Authenticity

You can use Run() instead, save the process id and check with ProcessExists() and the PID. This way, the Adlib function may have a chance to be executed.

Share this post


Link to post
Share on other sites
rudi

Hi.

You can use Run() instead, save the process id and check with ProcessExists() and the PID.

I've thought of that, too. But I can't see how to catch the exit code of a program started through run() instead of runwait()?

Regards, Rudi.


Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites
Tvern

Adlib is set to operate every 1000ms or every second, so the default 250ms is not being used.

I was referring to the one inside the loop, but that doesn't seem to be the problem.

Hi.

I've thought of that, too. But I can't see how to catch the exit code of a program started through run() instead of runwait()?

Regards, Rudi.

I don't know robocopy, but I imagine you might be able to use StdoutRead(), or StderrRead()?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×