dirms_gui.au3

#include <GUIConstants.au3>
 
#cs
 
    dirms.exe Gui by Wolfgang Führer
    wolfgang.fuehrer@web.de
    03.02.2005
 
    (Tweaked by THM 24.07.2006 to exit properly on single jobs)
 
    build with AutoIt 3.1.1
 
    show log availiable only with ABLogFile.exe from http://www.amleth.com/ablogfile/
 
    put dirms.exe and dirms_gui.exe and ABLogFile.exe in one folder to execute
 
#ce
 
AutoItSetOption("WinTitleMatchMode", 2)
 
 
Dim $drives ; array for drives
$drives = DriveGetDrive( "all")
$version = "0.3.4"
$infotext = " " & @CRLF & _
        "GUI for Defrag program - dirms.exe - by Leroy Dissinger " & @CRLF & _
        "                   http://www.dirms.com" & @CRLF & @CRLF & _
        "-------------------------------------------------------" & @CRLF & @CRLF & _
        "                 GUI by Wolfgang Führer" & @CRLF & _
        "                        Version " & $version & @CRLF & _
        "          http://www.wolfgang-fuehrer.de" & @CRLF & @CRLF & _
        "-------------------------------------------------------" & @CRLF & @CRLF & _		
        "         See helpfile.htm for more information."
 
Dim $checkboxid[$drives[0] + 1] ; array for checkboxes - number of drives
Dim $driveischecked[$drives[0] + 1] ; array for checked drives
Dim $msg[2] ; number of windows
Dim $isrunning = 0 ; 1 = dirms.exe is running
Dim $leftdrives = 0 ; drives to defrag
Dim $labelstatus = 0 ; 0 = not changed, 1 = start defrag label set, 2 = end label set
Dim $progresscounter = 0 ; counter for progress bar
Dim $ablogfileisrunning = 0 ; ABLogFile open 1 = yes
Dim $defraglogopen = 0 ;
Dim $defragstate = 0 ; 0=defrag button not pressed, 1=pressed, 2=finished/aborted
Dim $file ; file handle for logfile
Dim $currentdriveid = 0 ; drives begin at 1
Dim $shutdownisrunning
Dim $informationisshown = 0 ; infobox when ABLogFile.exe is not found but log should be shown while writing
Dim $begin ; start of time measuring
Dim $logfile ; build name for logfile
Dim $functiontext ; parameter for commandline
Dim $driveletter ; letter of drive
Dim $logfile ; name of logfile
Dim $drives ; array of drives
Dim $functiontext ; explanation
Dim $mode ; command line parameter
Dim $beginall ; timer begin pressing "do it" button ...
Dim $begin ; timer begin
Dim $iTicks
Dim $iHours
Dim $iTicks
Dim $iMins
Dim $iSecs
Dim $i ; drive index
Dim $logarray ; position of ablogfile window
Dim $mousearray ; mouse position
Dim $fulljobstate ; 1 = on
Dim $fulljoblevel ; 1 = -q , 2 = CoMpAcT , 3 = moce lcn , 4 = CoMpAcT , 5 = move lcn
Dim $fulljobstring = ""
Dim $topstring1 = "|===-==--==---=-======-----=== == ==-------==--=--==---==------==-----==-----=-===-=--===-----|"
Dim $topstring2 = "|===-==--==---=-======-----=== == ==-------==--=--==---==------==-----===|"
 
 
$guiheight = $drives[0] * 25 + 120 ; calculated height of gui
If $guiheight < 370 Then $guiheight = 370
$guiwidth = 550
 
; main GUI creation ============================================
$mainwin = GUICreate("DIRMS - Defrag - GUI " & $version, $guiwidth, $guiheight) ; main gui
 
if FileExists("DiskView.exe") then
	GUICtrlCreateLabel($topstring2, 47, 30, 320, 16, $SS_SIMPLE) ; program info
Else
	GUICtrlCreateLabel($topstring1, 47, 30, 405, 16, $SS_SIMPLE) ; program info
EndIf
$progressbar = GUICtrlCreateProgress($guiwidth - 359, $guiheight - 75, 173, 15, $PBS_SMOOTH)
$abort_btn = GUICtrlCreateButton(" - ", $guiwidth - 285, $guiheight - 45, 100, 25) ; cancel button
$timerid = GUICtrlCreateLabel("00:00:00", $guiwidth - 355, $guiheight - 40, 50, 15, $SS_SUNKEN + $SS_CENTER)
$windefrag = GUICtrlCreateButton("Win Defrag", $guiwidth - 90, 25, 75, 25) ; windows defrag button
 
; define drives group ===========================================
$l_drives = 15 ; left beginning drive group
$t_drives = 70 ; top beginning drive group
GUICtrlCreateGroup("Select Drives", $l_drives, $t_drives, 160, 25 * $drives[0] + 30) ; group drive lines
; make checkboxes for all drives
For $i = 1 To $drives[0] ; create checkboxes for all drives
    GUICtrlCreateLabel(StringUpper($drives[$i]) & "\", $l_drives + 12, 25 * $i + $t_drives + 3, 20, 20) ; drive letter
    ; defrag not for CDROM, Network and RAMDisk
    If DriveGetType($drives[$i] & "\") <> "CDROM" And DriveGetType($drives[$i] & "\") <> "Network" And DriveGetType($drives[$i] & "\") <> "RAMDisk" Then
        $checkboxid[$i] = GUICtrlCreateCheckbox(" ", $l_drives + 35, 25 * $i + $t_drives, 10, 20)
    EndIf
    $drivelabel = DriveGetType($drives[$i] & "\")
    if $drivelabel = "Fixed" Then $drivelabel = "Partition"
    GUICtrlCreateLabel($drivelabel, $l_drives + 55, 25 * $i + $t_drives + 2, 90, 15, $SS_SUNKEN) ; drive type
Next
 
; define actions group ==========================================
$l_action = 190
$t_action = 70
GUICtrlCreateGroup("Select Action", $l_action, $t_action, 175, 210) ; group line
$action0 = GUICtrlCreateRadio("Full job (5 Steps)", $l_action + 15, $t_action + 25, 140)
GUICtrlSetState($action0, $GUI_CHECKED)
$action1 = GUICtrlCreateRadio("Defrag and pack", $l_action + 15, $t_action + 50, 140) ; Do free space evaluation, defrag, and quickly move files to the front of hdd
$action2 = GUICtrlCreateRadio("Defrag only", $l_action + 15, $t_action + 75, 140) ; Defragment files only
$action3 = GUICtrlCreateRadio("Compact only", $l_action + 15, $t_action + 100, 140) ; Compact only
$action4 = GUICtrlCreateRadio("Partial compaction (quick)", $l_action + 15, $t_action + 125, 140) ; Perform partial compaction (quickly) on all fragmented files
$action5 = GUICtrlCreateRadio("Move files by date", $l_action + 15, $t_action + 150, 140) ; Move files according to modification dates, and do it quickly
$action6 = GUICtrlCreateRadio("Move to front (pack)", $l_action + 15, $t_action + 175, 140) ; Try to free space at the bottom of the drive (Move files to front)
 
 
; define final actions groups ====================================
$l_enhance = 380
$t_enhance = 70
GUICtrlCreateGroup("Logging", $l_enhance, $t_enhance, 155, 85) ; group line
$writelog = GUICtrlCreateCheckbox("Write Logfile", $l_enhance + 15, $t_enhance + 25, 100, 20)
;GUICtrlSetState($writelog, $GUI_CHECKED)
$showlog = GUICtrlCreateCheckbox("Show Logfile", $l_enhance + 15, $t_enhance + 50, 100, 20)
;GUICtrlSetState($showlog, $GUI_CHECKED)
 
GUICtrlCreateGroup("Exit", $l_enhance, $t_enhance + 100, 155, 110) ; group line
$exit = GUICtrlCreateRadio("Finish with exit", $l_enhance + 15, $t_enhance + 125, 120, 20)
$logoff = GUICtrlCreateRadio("Finish with logoff", $l_enhance + 15, $t_enhance + 150, 120, 20)
$shutdown = GUICtrlCreateRadio("Finish with shutdown", $l_enhance + 15, $t_enhance + 175, 120, 20)
;$enhance5 = GUICtrlCreateCheckbox("Save settings", $l_enhance + 15, $t_enhance + 125, 120, 20) ; not ready yet
 
$defrag_btn = GUICtrlCreateButton("Do it ...", $guiwidth - 115, $guiheight - 80, 100, 25, $BS_DEFPUSHBUTTON) ; "defrag" button
$exit_btn = GUICtrlCreateButton("Exit", $guiwidth - 115, $guiheight - 45, 100, 25) ; "exit" button
$info = GUICtrlCreateButton("?", 15, 25, 25, 25) ; "?" button (for about box)
if FileExists("DiskView.exe") then
    $sysinternals = GUICtrlCreateButton("DiskView", $guiwidth - 170, 25, 65, 25)
Else
    $sysinternals = ""
EndIf
 
 
GUISetState(@SW_SHOW)       ; display gui
 
 
;=========================================================================================
; main gui loop
;=========================================================================================
While 1 ; Run the GUI until the dialog is closed
    $msg = GUIGetMsg(1)
    Select
        Case $msg[0] = $GUI_EVENT_CLOSE And $msg[1] = $mainwin ; close by cross
            ExitLoop
        Case $msg[0] = $info And $msg[1] = $mainwin ; info button
            MsgBox(64, "Program Info", $infotext)
        Case $msg[0] = $exit_btn And $msg[1] = $mainwin ; "Cancel" button
            ExitLoop
		Case $msg[0] = $sysinternals And $msg[1] = $mainwin ; "DiskView" button
            Run("DiskView.exe")
        Case $msg[0] = $windefrag And $msg[1] = $mainwin ; "Win defrag" button
            Run('"' & @SystemDir & '\mmc.exe" "' & @SystemDir & '\dfrg.msc" c:')
        Case $msg[0] = $defrag_btn And $msg[1] = $mainwin ; "do it" button
            $defragstate = 1
            $beginall = TimerInit()
            $informationisshown = 0
        Case $msg[0] = $abort_btn And $msg[1] = $mainwin ; abort defrag
            If $isrunning = 1 Then
                WinSetState("DIRMS cmd Defrag", "", @SW_SHOW)
                WinActivate("DIRMS cmd Defrag")
                Send("^c")
                WinSetState("DIRMS cmd Defrag", "", @SW_MINIMIZE)
                ControlSetText("DIRMS - Defrag", "Abort", "Button1", "Please wait ...")
                For $i = 1 To $drives[0] ; look for all checked drives
                    If GUICtrlRead($checkboxid[$i]) = $GUI_CHECKED Then ; drive checked ?
                        GUICtrlSetState($checkboxid[$i], $GUI_UNCHECKED)
                    EndIf
                Next ;==> count number of checked drives in $leftdrives
                $leftdrives = 0 ; no more defrag please
                $defragstate = 0
                WinWaitClose("DIRMS cmd Defrag", "", 5)
                ControlSetText("DIRMS - Defrag", "", "Static" & 2 + 2 * $currentdriveid, " -> aborted ")
                $labelstatus = 2 ; otherwise "defrag finished" will be created over in no action running block
                If $defraglogopen = 1 Then ; write logfile is open
                    $iTicks = TimerDiff($begin)
                    $iTicks = Round($iTicks / 1000)
                    $iHours = Int($iTicks / 3600)
                    $iTicks = Mod($iTicks, 3600)
                    $iMins = Int($iTicks / 60)
                    $iSecs = Round(Mod($iTicks, 60))
                    $file = FileOpen($logfile, 1)
                    If $file = -1 Then
                        MsgBox(0, "Error", "Unable to open file " & $logfile & ".")
                        Exit
                    EndIf
                    FileWrite($file, " " & @CRLF)
                    FileWrite($file, "----------------------------------------------------------------" & @CRLF)
                    FileWrite($file, " " & @HOUR & ":" & @MIN & ":" & @SEC & " - " & $functiontext & " - Drive " & $driveletter & ":\ - aborted!" & @CRLF)
                    FileWrite($file, " Time: " & $iHours & " h " & $iMins & " min " & $iSecs & " sec" & @CRLF)
                    FileWrite($file, "----------------------------------------------------------------" & @CRLF)
                    FileClose($file)
                    $defraglogopen = 0
                    WinClose("ABLogFile -")
                EndIf
 
            EndIf
    EndSelect
    ; button actions end
 
    ; jobs beside the buttons ==============================================
 
    ; check status
    $progresscounter = $progresscounter + 1 ; animate progress bar
    If $progresscounter = 100 Then
        $progresscounter = 5
    EndIf
    If WinExists("DIRMS cmd Defrag", "") Then ; set flag of running cmd action 1 = running
        $isrunning = 1
    Else
        $isrunning = 0
    EndIf
    $leftdrives = 0
    For $i = 1 To $drives[0] ; look for all checked drives
        If GUICtrlRead($checkboxid[$i]) = $GUI_CHECKED Then ; drive checked ?
            $leftdrives = $leftdrives + 1
        EndIf
    Next ;==> count number of checked drives in $leftdrives
	if $leftdrives = 0 and $defragstate = 1 Then ;if pressed DoIt but no drive was checked
		$defragstate = 0                         ;set back action
	EndIf
    if $isrunning = 1 and $leftdrives = 0 Then ; defrag finished
		$defragstate = 2
	EndIf
 
    ; no action running	=====================================================
    If $isrunning = 0 Then ; when no action is running
        GUICtrlSetData($progressbar, 0) ; blank progress bar when no action is in progress
        ControlSetText("DIRMS - Defrag", "", "Button1", " - ") ; change abort button text
        If $labelstatus = 1 Then
            ControlSetText("DIRMS - Defrag", "", "Static" & 2 + 2 * $currentdriveid, " -> finished ")
            $labelstatus = 2
        EndIf
        If $defraglogopen = 1 Then ; write logfile is still open -> close
            $iTicks = TimerDiff($begin)
            $iTicks = Round($iTicks / 1000)
            $iHours = Int($iTicks / 3600)
            $iTicks = Mod($iTicks, 3600)
            $iMins = Int($iTicks / 60)
            $iSecs = Round(Mod($iTicks, 60))
            $file = FileOpen($logfile, 1)
            If $file = -1 Then
                MsgBox(0, "Error", "Unable to open file " & $logfile & " at end of defrag.")
                Exit
            EndIf
            FileWrite($file, " " & @CRLF)
            FileWrite($file, "----------------------------------------------------------------" & @CRLF)
            FileWrite($file, " " & @HOUR & ":" & @MIN & ":" & @SEC & " - " & $functiontext & " - Drive " & $driveletter & ":\ - finished" & @CRLF)
            FileWrite($file, " Time: " & $iHours & " h " & $iMins & " min " & $iSecs & " sec" & @CRLF)
            FileWrite($file, "----------------------------------------------------------------" & @CRLF)
            FileClose($file)
            $defraglogopen = 0
            Sleep(1000)
            WinClose("ABLogFile -")
            $ablogfileisrunning = 0
        EndIf
        If $leftdrives = 0 And $defragstate = 2 Then ; no more drives to defrag but was running
            $defragstate = 0
			If GUICtrlRead($shutdown) = $GUI_CHECKED And $shutdownisrunning = 0 Then ; shutdown
                 _RunDOS('shutdown -s -t 60 -c "Shutdown after defrag ..."')
				;MsgBox(0,"","Shutdown")
				;Exit
                $shutdownisrunning = 1
            EndIf
			If GUICtrlRead($logoff) = $GUI_CHECKED And $shutdownisrunning = 0 Then ; logoff
                 _RunDOS('shutdown -l -t 30 -c "Logoff after defrag ..."')
				;MsgBox(0,"","Logoff")
				;Exit
                $shutdownisrunning = 1
            EndIf
            If GUICtrlRead($exit) = $GUI_CHECKED Then ; exit
                Exit
            EndIf
        EndIf
    EndIf ; no action running
 
 
    ; do defragging ================================================
    If $leftdrives > 0 And $defragstate = 1 And $isrunning = 0 Then ; more drives to defrag and defrag button pressed ?
        For $i = 1 To $drives[0] ; look for next checked drive
            If GUICtrlRead($checkboxid[$i]) = $GUI_CHECKED Then ; drive checked ?
                $currentdriveid = $i
                $progresscounter = 5
                GUICtrlSetData($progressbar, $progresscounter)
                ; build command string
                If GUICtrlRead($action0) = $GUI_CHECKED Then ; full job
                    if $fulljobstate = 0 Then
                        $fulljobstate = 1
                        $fulljoblevel = 1
                    EndIf
                    if $fulljobstate = 1 Then
                        If $fulljoblevel = 1 Then
                            $mode = "-q"
                            $functiontext = "Full job 1/5"
                            $fulljobstring = "1/5"
                        EndIf
                        If $fulljoblevel = 2 Then
                            $mode = "CoMpAcT"
                            $functiontext = "Full job 2/5"
                            $fulljobstring = "2/5"
                        EndIf
                        If $fulljoblevel = 3 Then
                            $mode = "move lcn"
                            $functiontext = "Full job 3/5"
                            $fulljobstring = "3/5"
                        EndIf
                        If $fulljoblevel = 4 Then
                            $mode = "CoMpAcT"
                            $functiontext = "Full job 4/5"
                            $fulljobstring = "4/5"
                        EndIf
                        If $fulljoblevel = 5 Then
                            $mode = "move lcn"
                            $functiontext = "Full job 5/5"
                            $fulljobstring = "5/5"
                        EndIf
                    EndIf
                ElseIf GUICtrlRead($action1) = $GUI_CHECKED Then
                    $mode = "-q"
                    $functiontext = "Defrag and pack"
                ElseIf GUICtrlRead($action2) = $GUI_CHECKED Then
                    $mode = "DEFRAG -q"
                    $functiontext = "Defrag only"
                ElseIf GUICtrlRead($action3) = $GUI_CHECKED Then
                    $mode = "CoMpAcT -q"
                    $functiontext = "Compact only"
                ElseIf GUICtrlRead($action4) = $GUI_CHECKED Then
                    $mode = "COMFRAG -q"
                    $functiontext = "Partial compaction (quick)"
                ElseIf GUICtrlRead($action5) = $GUI_CHECKED Then
                    $mode = "move date -q"
                    $functiontext = "Move files by date"
                ElseIf GUICtrlRead($action6) = $GUI_CHECKED Then
                    $mode = "move lcn"
                    $functiontext = "Move to front (pack)"
                EndIf
                $driveletter = StringLeft($drives[$i], 1) ; set drive letter
                $logfile = "defrag_" & $driveletter & ".log"
                If GUICtrlRead($writelog) = $GUI_CHECKED Then ; write logfile checked
                    $mode = $mode & ">>" & $logfile
                    FileDelete($logfile) ; delete old logfile
                    $file = FileOpen($logfile, 1)
                    If $file = -1 Then
                        MsgBox(0, "Error", "Unable to open logfile " & $logfile & "." & @CRLF & @CRLF & "Action on " & $driveletter & ":\ just running?")
                        Exit
                    EndIf
                    ; write header
                    FileWrite($file, "------------------------------------------------------------------------" & @CRLF)
                    FileWrite($file, " " & @HOUR & ":" & @MIN & ":" & @SEC & " - " & $functiontext & " - Drive " & $driveletter & ":\" & @CRLF)
                    FileWrite($file, " Command: dirms.exe " & $driveletter & " " & $mode & @CRLF)
                    FileWrite($file, "------------------------------------------------------------------------" & @CRLF)
                    FileWrite($file, " " & @CRLF)
                    FileClose($file)
                    $defraglogopen = 1
                EndIf
                $begin = TimerInit()
				; MsgBox(0,"","dirms.exe " & $driveletter & " " & $mode & @crlf & $fulljobstate & ":" & $fulljoblevel)
                ; commandstring =================================
                _RunDOS("Title DIRMS cmd Defrag & dirms.exe " & $driveletter & " " & $mode)
                $isrunning = 1
                ControlSetText("DIRMS - Defrag", " - ", "Button1", "Abort")
                ControlSetText("DIRMS - Defrag", "", "Static" & 2 + 2 * $currentdriveid, " => working " & $fulljobstring & " ... ")
                WinWaitActive("DIRMS cmd Defrag", "", 2)
                $labelstatus = 1
                if ($fulljobstate = 1 And $fulljoblevel = 5) or $fulljobstate = 0 Then
                    GUICtrlSetState($checkboxid[$i], $GUI_UNCHECKED)
                    $fulljobstring = ""
                    $fulljobstate = 0
                Else
                    $fulljoblevel = $fulljoblevel +1
                EndIf
                ExitLoop ; only first found drive! then back to gui
            EndIf
        Next ; Drive
    EndIf ; of "do defragging"
 
    ; action is still running ========================================================
    If $isrunning = 1 Then
        GUICtrlSetData($progressbar, $progresscounter) ; redraw progress bar when action is running
        $iTicks = TimerDiff($beginall)
        $iTicks = Round($iTicks / 1000)
        $iHours = Int($iTicks / 3600)
        $iTicks = Mod($iTicks, 3600)
        $iMins = Int($iTicks / 60)
        $iSecs = Round(Mod($iTicks, 60))
        $timerstring = StringRight("0" & $iHours, 2) & ":" & StringRight("0" & $iMins, 2) & ":" & StringRight("0" & $iSecs, 2)
        ControlSetText("DIRMS - Defrag", "", "Static2", $timerstring)
 
        If FileExists("ABLogFile.exe") And GUICtrlRead($showlog) = $GUI_CHECKED And $defraglogopen = 1 Then
            If $ablogfileisrunning = 0 Then
                Run("ABLogFile.exe " & "defrag_" & $driveletter & ".log")
                WinWaitActive("ABLogFile -")
                $logarray = WinGetPos("ABLogFile -")
                $mousearray = MouseGetPos()
                MouseClick("left",$logarray[0]+40,$logarray[1]+70,2)
                MouseMove($mousearray[0],$mousearray[1])
                $ablogfileisrunning = 1
            EndIf
        EndIf
        If GUICtrlRead($showlog) = $GUI_CHECKED And GUICtrlRead($writelog) = $GUI_UNCHECKED And $defraglogopen = 0 Then
            WinSetState("DIRMS cmd Defrag", "", @SW_SHOWDEFAULT)
        EndIf
        If GUICtrlRead($showlog) = $GUI_UNCHECKED Then
            WinSetState("DIRMS cmd Defrag", "", @SW_MINIMIZE)
            WinClose("ABLogFile -")
            WinWaitClose("ABlogFile -", 5)
            $ablogfileisrunning = 0
        EndIf
        If GUICtrlRead($showlog) = $GUI_CHECKED And GUICtrlRead($writelog) = $GUI_CHECKED And Not FileExists("ABLogFile.exe") And $informationisshown = 0 Then
            MsgBox(48, "Information", "ABLogFile.exe not found" & @CRLF & @CRLF & "See " & $logfile & " after defrag", 10)
            $informationisshown = 1
        EndIf
    EndIf ; of "action is still running"
WEnd ; GUI loop end
 
 
Func _RunDOS($sCommand)
    Return Run(@ComSpec & " /C " & $sCommand, "", @SW_HIDE)
EndFunc   ;==>_RunDOS