Jump to content

(solved) Reading console input from Autoit script compiled as CLI


Recommended Posts

Hey everybody.  I'm trying my hand at a duplicate file remover (customized the way I like it of course), which is compiled as a command line utility.  So what I start doing is having user select destination (where files are going) and source (where they are coming from) directories.  If the file/folder does not exist in destination, file/folder is moved there.   Now here is where I run into my issue.  If the file (folders are skipped, just have the filemove operation create the path if applicable) is located in the destination directory, I first use Microsoft's File Checksum Integrity Verifier command line utility to see if, even if they have the same name, they are the same file by comparing the hash values of both files.  If the files are not the same based on comparing the generated hashes, I would like the command prompt to inform the user that this is the case, and then allow them to input a selection into the command prompt to determine what the script does next.  However, I don't seem to be doing it right, as it doesn't seem to be reading anything I enter.  There are two potential ways I would like the console to behave when accepting user input: 1) immediately perform the action indicated by user without the need to press "Enter" and 2) opposite of 1 (requires enter to be pressed in order to continue).  Any help would be AWESOME.  I'll mark in the code the problem area.  Also, the File Checksum Integrity Verifier command line utility is not pre-packaged with windows, so you may have to download it and add it to your PATH in order to test/use the script (https://www.microsoft.com/en-us/download/details.aspx?id=11533).  Thank you in advance.

 

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; *** Start added by AutoIt3Wrapper ***
#include <FileConstants.au3>
; *** End added by AutoIt3Wrapper ***
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.15.0 (Beta)
 Author:         myName

 Script Function:
    Template AutoIt script.

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

; Script Start - Add your code below here
#include <File.au3>
#include <Array.au3>
#include <Date.au3>

$a = FileSelectFolder ( "Select destination", "" )
$b = FileSelectFolder ( "Select source", "" )
$dest = _FileListToArrayRec ( $a, "*", $FLTA_FILESFOLDERS )
$source = _FileListToArrayRec ( $b, "*", $FLTA_FILESFOLDERS )
$foldhold = ""
For $i = 1 To $source[0] Step 1
    $filepathstring = ""
    $justfile = StringSplit ( $source[$i], "\" )
    If @error Then
        SetError (0)
        $justfile = $source[$i]
    Else
        If $justfile[0] = 2 Then
            $filepathstring = "\" & $justfile[1]
        ElseIf $justfile[0] = 3 Then
            $filepathstring = "\" & $justfile[1] & "\" & $justfile[2]
        ElseIf $justfile[0] > 3 Then
            For $p = 1 To $justfile[0] - 1 Step 1
                $filepathstring = $filepathstring & "\" & $justfile[$p]
            Next
        Else

        EndIf
        $justfile = $justfile[$justfile[0]]
    EndIf
    $index = _ArraySearch ( $dest, $source[$i] )
    If @error Then
        SetError (0)
        ConsoleWrite ( "Copying " & $source[$i] & @CRLF )
        If IsFile ( $b & "\" & $source[$i] ) = 0 Then
            DirMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_CREATEPATH )
        Else
            FileMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_CREATEPATH )
        EndIf
    Else
        If IsFile ( $b & "\" & $source[$i] ) = 0 Then
            ContinueLoop
        Else
            $hash = Run ( "fciv -add " & '"' & $a & "\" & $dest[$index] & '"' & " -sha1", @SystemDir, @SW_SHOW, $STDOUT_CHILD )
            ProcessWaitClose ( $hash )
            $hash2 = Run ( "fciv -add " & '"' & $b & "\" & $source[$i] & '"' & " -sha1", @SystemDir, @SW_SHOW, $STDOUT_CHILD )
            ProcessWaitClose ( $hash2 )
            $hashstring = StringTrimLeft ( StringTrimRight ( StdoutRead ( $hash ), 2 ), 58 )
            $hashstring2 = StringTrimLeft ( StringTrimRight ( StdoutRead ( $hash2 ), 2 ), 58 )
            $firstsplit = StringInStr ( $hashstring, " " ) - 1
            $secondsplit = StringInStr ( $hashstring2, " " ) - 1
            $hashstring = StringLeft ( $hashstring, $firstsplit )
            $hashstring2 = StringLeft ( $hashstring2, $secondsplit )
            $num = 0
            If StringCompare ( $hashstring, $hashstring2 ) <> 0 Then
                ;PROBLEM BEGINS HERE
                ConsoleWrite ( "The file to be copied from the source has the same file name as a file in the destination, but the hash values are different.  What do you want to do?" & @CRLF & "[R]ename   [D]elete   [M]ove(Replace)" & @CRLF )
                Do
                    $user = ConsoleRead ()
                    Sleep ( 150 )
                Until $user == "r" Or $user == "R" Or $user == "d" Or $user == "D" Or $user == "m" Or $user == "M"
                Select
                    Case $user == "r" Or $user == "R"
                        $rename = StringSplit ( $justfile, "." )
                        $newname = ""
                        If $filepathstring == "" Then
                            Do
                                $num += 1
                                If $rename[0] = 2 Then
                                    $newname = $rename[1] & "(" & $num & ")." & $rename[2]
                                Else
                                    For $f = 1 To $rename[0] Step 1
                                        If $f = 1 Then
                                            $newname = $rename[$f]
                                            ContinueLoop
                                        EndIf

                                        If $f = $rename[0] - 1 Then
                                            $newname = $newname & "." & $rename[$f] & "(" & $num & ")"
                                        Else
                                            $newname = $newname & "." & $rename[$f]
                                        EndIf
                                    Next
                                EndIf
                            Until Not FileExists ( $a & "\" & $newname )
                            Do
                                FileMove ( $b & "\" & $source[$i], $a & "\" & $newname )
                            Until Not FileExists ( $b & "\" & $source[$i] )
                        Else
                            Do
                                $num += 1
                                If $rename[0] = 2 Then
                                    $newname = $rename[1] & "(" & $num & ")." & $rename[2]
                                Else
                                    For $f = 1 To $rename[0] Step 1
                                        If $f = 1 Then
                                            $newname = $rename[$f]
                                            ContinueLoop
                                        EndIf
                                        If $f = $rename[0] - 1 Then
                                            $newname = $newname & "." & $rename[$f] & "(" & $num & ")"
                                        Else
                                            $newname = $newname & "." & $rename[$f]
                                        EndIf
                                    Next
                                EndIf
                            Until Not FileExists ( $a & $filepathstring & "\" & $newname )
                            Do
                                FileMove ( $b & "\" & $source[$i], $a & $filepathstring & "\" & $newname )
                            Until Not FileExists ( $b & "\" & $source[$i] )
                        EndIf


                    Case $user == "d" Or $user == "D"
                        Do
                            FileDelete ( $b & "\" & $source[$i] )
                        Until Not FileExists ( $b & "\" & $source[$i] )
                    Case $user == "m" Or $user == "M"
                        Do
                            FileMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_OVERWRITE )
                        Until Not FileExists ( $b & "\" & $source[$i] )
                EndSelect
                ;PROBLEM PROBABLY ENDS HERE
            Else
                $desttime = _Date_Time_GetFileTime ( $a & "\" & $dest[$index] )
                $sourcetime = _Date_Time_GetFileTime ( $b & "\" & $source[$i] )
                $compare = _Date_Time_CompareFileTime ( $desttime[2], $sourcetime[2] )
                If $compare = 0 Or $compare = 1 Then
                    ConsoleWrite ( "Deleting " & $source[$i] & @CRLF )
                    Do
                        FileDelete ( $b & "\" & $source[$i] )
                    Until Not FileExists ( $b & "\" & $source[$i] )
                ElseIf $compare = -1 Then
                    ConsoleWrite ( "Copying " & $source[$i] & @CRLF )
                    Do
                        FileMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_OVERWRITE )
                    Until Not FileExists ( $b & "\" & $source[$i] )
                Else
                    ConsoleWrite ( "????????????????????" )
                EndIf
            EndIf

        EndIf
    EndIf
Next



Func IsFile($sFilePath)
    Return Number(FileExists($sFilePath) And StringInStr(FileGetAttrib($sFilePath), "D", 2, 1) = 0)
EndFunc   ;==>IsFile

 

Edited by MattHiggs
Link to comment
Share on other sites

@MattHiggs,

ConsoleRead does not work as you might expect. it is meant to read the console input passed to it from whatever app (including the shell) that called it; it is not meant to read its own console.

if i wanted to write a fully-qualified console program, this is where i'd begin my quest:

 

 

 

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

On 10/8/2016 at 4:10 PM, orbs said:

@MattHiggs,

ConsoleRead does not work as you might expect. it is meant to read the console input passed to it from whatever app (including the shell) that called it; it is not meant to read its own console.

if i wanted to write a fully-qualified console program, this is where i'd begin my quest:

 

Thank you for your reply.  So I did try the UDF listed here, but when I try to use one of the functions in said UDF, it just skips the file when the script is run in a real-life example.   Normally I would post directly to the udf thread and ask why, but since it is relatively old, I figure I might as well ask here.  Here is the updated script, and I will see if I can't obtain some more information about what exactly is going on behind the scenes in the script during execution.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; *** Start added by AutoIt3Wrapper ***
#include <FileConstants.au3>
; *** End added by AutoIt3Wrapper ***
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.15.0 (Beta)
 Author:         myName

 Script Function:
    Template AutoIt script.

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

; Script Start - Add your code below here
#include <File.au3>
#include <Array.au3>
#include <Date.au3>
#include <Console.au3>

$a = FileSelectFolder ( "Select destination", "" )
$b = FileSelectFolder ( "Select source", "" )
$dest = _FileListToArrayRec ( $a, "*", $FLTA_FILESFOLDERS )
$source = _FileListToArrayRec ( $b, "*", $FLTA_FILESFOLDERS )
$foldhold = ""
For $i = 1 To $source[0] Step 1
    $filepathstring = ""
    $justfile = StringSplit ( $source[$i], "\" )
    If @error Then
        SetError (0)
        $justfile = $source[$i]
    Else
        If $justfile[0] = 2 Then
            $filepathstring = "\" & $justfile[1]
        ElseIf $justfile[0] = 3 Then
            $filepathstring = "\" & $justfile[1] & "\" & $justfile[2]
        ElseIf $justfile[0] > 3 Then
            For $p = 1 To $justfile[0] - 1 Step 1
                $filepathstring = $filepathstring & "\" & $justfile[$p]
            Next
        Else

        EndIf
        $justfile = $justfile[$justfile[0]]
    EndIf
    $index = _ArraySearch ( $dest, $source[$i] )
    If @error Then
        SetError (0)
        ConsoleWrite ( "Copying " & $source[$i] & @CRLF )
        If IsFile ( $b & "\" & $source[$i] ) = 0 Then
            DirMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_CREATEPATH )
        Else
            FileMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_CREATEPATH )
        EndIf
    Else
        If IsFile ( $b & "\" & $source[$i] ) = 0 Then
            ContinueLoop
        Else
            $hash = Run ( "fciv -add " & '"' & $a & "\" & $dest[$index] & '"' & " -sha1", @SystemDir, @SW_SHOW, $STDOUT_CHILD )
            ProcessWaitClose ( $hash )
            $hash2 = Run ( "fciv -add " & '"' & $b & "\" & $source[$i] & '"' & " -sha1", @SystemDir, @SW_SHOW, $STDOUT_CHILD )
            ProcessWaitClose ( $hash2 )
            $hashstring = StringTrimLeft ( StringTrimRight ( StdoutRead ( $hash ), 2 ), 58 )
            $hashstring2 = StringTrimLeft ( StringTrimRight ( StdoutRead ( $hash2 ), 2 ), 58 )
            $firstsplit = StringSplit ( $hashstring, " " )
            $secondsplit = StringSplit ( $hashstring2, " " )
            $num = 0
            If StringCompare ( $firstsplit[1], $secondsplit[1] ) <> 0 Then
                ;PROBLEM BEGINS HERE
                $user = ""
                ConsoleWrite ( "The file to be copied from the source has the same file name as a file in the destination, but the hash values are different.  What do you want to do?" & @CRLF & "[R]ename   [D]elete   [M]ove(Replace)" & @CRLF )
                $user = Getch ()
                Select
                    Case $user == "r" Or $user == "R"
                        $rename = StringSplit ( $justfile, "." )
                        $newname = ""
                        If $filepathstring == "" Then
                            Do
                                $num += 1
                                If $rename[0] = 2 Then
                                    $newname = $rename[1] & "(" & $num & ")." & $rename[2]
                                Else
                                    For $f = 1 To $rename[0] Step 1
                                        If $f = 1 Then
                                            $newname = $rename[$f]
                                            ContinueLoop
                                        EndIf

                                        If $f = $rename[0] - 1 Then
                                            $newname = $newname & "." & $rename[$f] & "(" & $num & ")"
                                        Else
                                            $newname = $newname & "." & $rename[$f]
                                        EndIf
                                    Next
                                EndIf
                            Until Not FileExists ( $a & "\" & $newname )
                            Do
                                FileMove ( $b & "\" & $source[$i], $a & "\" & $newname )
                            Until Not FileExists ( $b & "\" & $source[$i] )
                        Else
                            Do
                                $num += 1
                                If $rename[0] = 2 Then
                                    $newname = $rename[1] & "(" & $num & ")." & $rename[2]
                                Else
                                    For $f = 1 To $rename[0] Step 1
                                        If $f = 1 Then
                                            $newname = $rename[$f]
                                            ContinueLoop
                                        EndIf
                                        If $f = $rename[0] - 1 Then
                                            $newname = $newname & "." & $rename[$f] & "(" & $num & ")"
                                        Else
                                            $newname = $newname & "." & $rename[$f]
                                        EndIf
                                    Next
                                EndIf
                            Until Not FileExists ( $a & $filepathstring & "\" & $newname )
                            Do
                                FileMove ( $b & "\" & $source[$i], $a & $filepathstring & "\" & $newname )
                            Until Not FileExists ( $b & "\" & $source[$i] )
                        EndIf


                    Case $user == "d" Or $user == "D"
                        Do
                            FileDelete ( $b & "\" & $source[$i] )
                        Until Not FileExists ( $b & "\" & $source[$i] )
                    Case $user == "m" Or $user == "M"
                        Do
                            FileMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_OVERWRITE )
                        Until Not FileExists ( $b & "\" & $source[$i] )
                EndSelect
                ;PROBLEM PROBABLY ENDS HERE
            Else
                $desttime = _Date_Time_GetFileTime ( $a & "\" & $dest[$index] )
                $sourcetime = _Date_Time_GetFileTime ( $b & "\" & $source[$i] )
                $compare = _Date_Time_CompareFileTime ( $desttime[2], $sourcetime[2] )
                If $compare = 0 Or $compare = 1 Then
                    ConsoleWrite ( "Deleting " & $source[$i] & @CRLF )
                    Do
                        FileDelete ( $b & "\" & $source[$i] )
                    Until Not FileExists ( $b & "\" & $source[$i] )
                ElseIf $compare = -1 Then
                    ConsoleWrite ( "Copying " & $source[$i] & @CRLF )
                    Do
                        FileMove ( $b & "\" & $source[$i], $a & "\" & $source[$i], $FC_OVERWRITE )
                    Until Not FileExists ( $b & "\" & $source[$i] )
                Else
                    ConsoleWrite ( "????????????????????" )
                EndIf
            EndIf

        EndIf
    EndIf
Next



Func IsFile($sFilePath)
    Return Number(FileExists($sFilePath) And StringInStr(FileGetAttrib($sFilePath), "D", 2, 1) = 0)
EndFunc   ;==>IsFile

 

Ouch guys, ouch.  No reply in 12 hours?  Is it that nobody knows the answer to my question or that the answer is so painfully obvious that its not even worth the time to post the answer.  Ouch....My Pride.....

Link to comment
Share on other sites

Eurika!!  Finally figured out what was wrong.  For some reason, the UDF doesn't like it when the compiled script is compiled as a command line utility, as it works perfectly when run from Scite or as a GUI application.  Thanks for the help.

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...