Jump to content

How to stop a batch processing that uses an external command like Run(..)


Recommended Posts

Dear collegues,

Most of my scripts batch processes lists of files running external commads, and then do something with the result (like saving a log file).

They usually only have one "GO" button to start processing, but if I want to cancel the processing I have to "kill" the app. I could test if a "cancel" button was pressed between each of the external commands, but what I´m looking for is something to cancel the process right away. 

To help ilustrate the problem I´m including an example script. It uses an external EXE to generate MD5 hashes of the files in a provided directory. What I want is a button to "cancel" the processing, even that the external MD5.exe program is still running. Is it possible? Anyone have an idea?

Thanks in advance! 
Nomad_RJ

#include <File.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("Hash Exemple", 480, 225)
$sourcelabel = GUICtrlCreateLabel("Files to MD5:", 16, 10, 169, 17)
$soure_ctrl = GUICtrlCreateInput("", 16, 27, 450, 21)
$logpathlabel = GUICtrlCreateLabel("Output log:", 16, 53, 80, 17)
$logpath_ctrl = GUICtrlCreateInput("", 16, 70, 450, 21)
$subdir = GUICtrlCreateCheckbox("Include subdirs", 365, 8, 120, 17)
$StatusGroup = GUICtrlCreateGroup(" Status  ", 16, 100, 448, 73)
$status = GUICtrlCreateLabel("", 32, 128, 430, 42)
$run = GUICtrlCreateButton("Generate", 160, 187, 150, 25)
GUISetState(@SW_SHOW)

FileInstall(".\tools\md5.exe", @TempDir & "\", 1) ; 1=overwrite
GUICtrlSetData($logpath_ctrl, @ScriptDir&"\output.csv")
GUICtrlSetState($subdir,$GUI_CHECKED)

Do
    $nMsg = GUIGetMsg()
    If $nMsg = $run AND GuiCtrlRead($soure_ctrl) <> "" Then
        Global $FileCount = 0
        Local $recursive = 0
        Local $src = GuiCtrlRead($soure_ctrl)
        Local $log = GuiCtrlRead($logpath_ctrl)
        If GUICtrlRead($subdir) = $GUI_CHECKED Then $recursive = 1
        _RecLog($src, $log, $recursive)
        GUICtrlSetData($status, $FileCount & ' files processed')
    EndIf
Until $nMsg = $GUI_EVENT_CLOSE


Func _RecLog($path, $logfile, $sub)
    If StringRight($path,1) = "\" Then $path = StringLeft($path, StringLen($path)-1)
    Local $i = 1
    Local $j = 1
    Local $FileList = _FileListToArray($path, "*.*", 1) ;0(Default) both files and folders, 1 files only, 2 Folders only
    If NOT @error Then
        While $i <= $FileList[0]
            $FileCount = $FileCount + 1
            GUICtrlSetData($status, $FileCount&': '&$path&'\'&$FileList[$i])
            $hash = _GetHash($path&"\"&$FileList[$i])
            _SaveLog($logfile, '"' & $path&'\'&$FileList[$i] & '","' & $hash & '"' & @CRLF)
            $i = $i + 1
        WEnd
    EndIf
    Local $FolderList = _FileListToArray($path, "*", 2) ;0(Default) both files and folders, 1 files only, 2 Folders only
    If (NOT @error) AND $sub Then
        While $j <= $FolderList[0]
            _RecLog($path&"\"&$FolderList[$j],$logfile, $sub)
            $j = $j + 1
        WEnd
    EndIf
EndFunc


Func _SaveLog($path,$text)
    Local $file = FileOpen($path, 275)  ; = 1 (write) + 8 (create folder) + 128 (utf-8)
    FileWrite($file, $text)
    FileClose($file)
EndFunc


Func _GetHash($fullpathfile)
    $command = @TempDir&'\md5.exe "' & $fullpathfile & '"'
    $cmd = Run(@ComSpec & ' /c ' & $command, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    ProcessWaitClose($cmd)
    $md5 = StringLeft(StdoutRead($cmd), 32)
    Return $md5
EndFunc

 

Link to comment
Share on other sites

In addition to what jpm said, if you are using any DOS window (Command Prompt .... cmd.exe), then most of them will close more gracefully, with a sending of CTRL+BREAK.

You could also benefit looking at the AdLib functions, if you haven't done already ... and there are plenty of examples of their use here at the forum, either using a button (ID check or separate floating button from another EXE, etc) or by using a Hotkey (_IsPressed).

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...