CarlD Posted August 9 Share Posted August 9 (edited) I know there are other Updater scripts out there. Mine uses the file-hashing function in @TheXman's CryptoNG UDF to compare the user's (local) version with the current (remote) version of the subject file. First set the User Variables, then compile it with Change2CUI = y. Command-line options /Q and /QQ suppress console output. Option /? gives help. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseUpx=y #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Run_Au3Stripper=y #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs -------------------------- Updater.au3 -- C.L.Distefano rev. 2024-08-13 Template for Command-Line File Updater Compare local file to remote file; if not identical, (1) Back up local file; and (2) Update local file (overwrite with remote file) Credit: TheXMan, author of CryptoNG https://www.autoitscript.com/forum/files/file/490-cryptong-udf-cryptography-api-next-generation/ ------------------------------ #ce Global $sRevDate = "[C.L.Distefano rev. 2024-08-13]" #include ".\CryptoNG\CryptoNG.au3" #include <File.au3> #include <FileConstants.au3> #include <InetConstants.au3> #include <Process.au3> #include <StringConstants.au3> Global $sArgs = "", $sTmp Global $sLocalFn, $sRemoteFn, $sRemoteFnTmp, $sRemFname Global $sIniFile, $sLogFile, $d, $p, $f, $e, $h0 _PathSplit(@ScriptFullPath, $d, $p, $f, $e) $sIniFile = $d & $p & $f & ".ini" $sLogFile = $d & $p & $f & ".log" Global $bLogIt = 0, $bQuiet = 0 Global $sSection = "Default" If Not FileExists($sIniFile) Then $h0 = FileOpen($sIniFile, $FO_OVERWRITE) If $h0 > -1 Then FileWrite($h0, "; " & @ScriptName & " -- Settings" & @CRLF & @CRLF & "; How to Edit This File:" & @CRLF & "; Each [Section] lists the fully-qualified path to a local file to be" & @CRLF & "; updated (""LocalFile"") and a URL for the remote file (""RemoteFile"")," & @CRLF & "; i.e., the current version of the file. Name and populate your own sections" & @CRLF & "; accordingly. (See ""[Demo]"" below for an example.) To check the availability" & @CRLF & "; of updates for a given file, command """ & @ScriptName & " <SectionName>""." & @CRLF & "; For further help, command """ & @ScriptName & " /?""" & @CRLF & "; ------------------------------------------------------------------------" & @CRLF & @CRLF & "[Default]" & @CRLF & "LocalFile=" & @CRLF & "RemoteFile=" & @CRLF & @CRLF & "[Demo]" & @CRLF & "LocalFile=" & @ScriptDir & "\AAMilne6.txt" & @CRLF & "RemoteFile=https://www.gutenberg.org/cache/epub/70516/pg70516.txt" & @CRLF & @CRLF & "[File1]" & @CRLF & "LocalFile=" & @CRLF & "RemoteFile=" & @CRLF & @CRLF & "[File2]" & @CRLF & "LocalFile=" & @CRLF & "RemoteFile=" & @CRLF & @CRLF) FileClose($h0) Exit Run("notepad.exe " & $sIniFile) Else Exit _ExitErr("Error opening " & $sIniFile) EndIf EndIf If $CmdLine[0] > 0 Then $sArgs = _ArgGetRawArgs() If $sArgs Then If StringInStr($sArgs, "/?") Or StringInStr($sArgs, "-?") Or _ StringinStr($sArgs, "/h") Or StringInStr($sArgs, "-h") Or _ StringInStr($sArgs, "--help") Then Exit _ShowHelp() If StringInStr($sArgs, "/L") Then $bLogIt = 1 $sTmp = StringTrimLeft($sArgs, StringInStr($sArgs, "/L") + 1) If StringInStr($sTmp, '"') = 1 Then $sTmp = StringTrimLeft($sTmp, 1) If StringInStr($sTmp, '"') Then $sTmp = StringLeft($sTmp, StringInStr($sTmp, '"') - 1) ElseIf StringInStr($sTmp, " ") Then $sTmp = StringLeft($sTmp, StringInStr($sTmp, " ") - 1) EndIf If StringInStr($sTmp, ":") = 1 Then $sTmp = StringTrimLeft($sTmp, 1) If $sTmp Then $sLogFile = $sTmp ConsoleWrite($sLogFile & @CRLF) EndIf If StringInStr($sArgs, "/Q") Then $bQuiet = 1 If StringInStr($sArgs, "/QQ") Then $bQuiet = 2 EndIf If StringInStr($CmdLine[$CmdLine[0]], "/") <> 1 Then _ $sSection = $CmdLine[$CmdLine[0]] EndIf $sLocalFn = IniRead($sIniFile, $sSection, "LocalFile", "") $sRemoteFn = IniRead($sIniFile, $sSection, "RemoteFile", "") If Not ($sLocalFn And $sRemoteFn) Then Exit Run("notepad.exe " & $sIniFile) _PathSplit($sRemoteFn, $d, $p, $sRemFname, $e) Global $hI = -1 Global $xHashLocal, $xHashRemote Global $sTmpBaseDir = @TempDir If Not FileExists($sTmpBaseDir) Then $sTmpBaseDir = @ScriptDir Global $sTempDir = _TempFile($sTmpBaseDir) _CreateDir($sTempDir) If StringRight($sTempDir, 1) = "\" Then $sTempDir = StringTrimRight($sTempDir, 1) $sRemoteFnTmp = $sTempDir & "\" & $sRemFname If $bQuiet < 1 Then ConsoleWrite("Checking for updates...") $hI = InetGet($sRemoteFn, $sRemoteFnTmp, $INET_FORCERELOAD) If Not $hI Then _ConsoleEraseLine("Checking for updates...") If StringInStr($sArgs, "/L") Then _LogEntry("Download failed") If $bQuiet < 1 Then ConsoleWrite("Cleaning up...") _CleanUp() _ConsoleEraseLine("Cleaning up...") If $bQuiet < 2 Then ConsoleWrite(@CRLF & "Download failed!" & @CRLF) Exit 1 EndIf InetClose($hI) Sleep(1500) $xHashLocal = _CryptoNG_HashFile($CNG_BCRYPT_SHA256_ALGORITHM, $sLocalFn) $xHashRemote = _CryptoNG_HashFile($CNG_BCRYPT_SHA256_ALGORITHM, $sRemoteFnTmp) _ConsoleEraseLine("Checking for updates...") If $xHashRemote = $xHashLocal Then If StringInStr($sLocalFn, " ") Then $sLocalFn = """" & $sLocalFn & """" If $bQuiet < 1 Then _ConsoleWriteANSI($sLocalFn) If $sSection = "Default" Then _ConsoleWriteANSI(" (the default file)") _ConsoleWriteANSI(" is up to date!" & @CRLF) If $bLogIt Then _LogEntry("Up to date") EndIf Else If $bQuiet > 0 Then _DoUpdate() Else _ConsoleWriteANSI("Update available", 37, 41) ConsoleWrite(" for " & $sLocalFn) If $sSection = "Default" Then ConsoleWrite(" (the default file)") ConsoleWrite(@CRLF & "Get it now? (Y|N)" & @CRLF) While 1 Switch StringLeft(StringUpper(ConsoleRead()), 1) Case "Y" _DoUpdate() ExitLoop Case "N" If $bLogIt Then _LogEntry("Update available") ExitLoop Case Else Sleep(25) EndSwitch WEnd EndIf EndIf _CleanUp() Exit 0 ;----- Func _ArgGetRawArgs() ; Returns CMline arguments only Local $sOut = "", $sTmp If $CmdLine[0] Then For $i = 1 To $CmdLine[0] $sTmp = $CmdLine[$i] If StringInStr($sTmp, " ") Then $sTmp = """" & $sTmp & """" $sOut &= $sTmp If $i < $CmdLine[0] Then $sOut &= " " Next EndIf Return $sOut EndFunc ;==>_ArgGetRawArgs() Func _DoUpdate() If FileExists($sLocalFn) Then Local $sBackupFn _PathSplit($sLocalFn, $d, $p, $f, $e) $sBackupFn = $d & $p & $f & "-" & StringRight(@YEAR, 2) & _ @MON & @MDAY & "T" & @HOUR & @MIN & @SEC If $e Then $sBackupFn &= $e If Not FileCopy($sLocalFn, $sBackupFn) Then If $bQuiet < 2 Then _ConsoleWriteANSI("Error backing up " & _ $sLocalFn & "!" & @CRLF, 36, 1) EndIf EndIf If FileCopy($sRemoteFnTmp, $sLocalFn, $FC_OVERWRITE) Then If $bQuiet < 1 Then _ConsoleWriteANSI($sLocalFn & " was successfully updated!" & @CRLF) Else If $bQuiet < 2 Then _ConsoleWriteANSI("Error copying update to " & _ $sLocalFn & "!" & @CRLF, 36, 1) EndIf If $bLogIt Then _LogEntry("Updated") EndIf EndFunc ;==>_DoUpdate Func _CleanUp() Local $c = 0 While FileExists($sTempDir) RunWait("cmd.exe /c cd/d " & @ScriptDir & " &del/f/q " & $sTempDir & "\* >nul 2>nul &rd/s/q " & $sTempDir & " >nul 2>nul", @ScriptDir, @SW_HIDE) If $c > 300 Then ExitLoop Sleep(200) $c += 1 WEnd EndFunc ;==>CleanUp Func _ConsoleEraseLine($vIn) ; Erase one line (only) from console output ; Line to be erased must not terminate with Cr|Lf! If StringRight(String($vIn), 1) = @LF Then Return Local $sOut = "" If Not IsInt($vIn) Then $vIn = StringLen(String($vIn)) For $i = 1 To $vIn $sOut &= Chr(8) & " " & Chr(8) Next ConsoleWrite($sOut) Return EndFunc ;==>_ConsoleErase Func _ConsoleWriteANSI($sTxt, $iFg1 = 33, $iBg1 = 1, $iFg0 = 22, $iBg0 = 0) ; Write colorful text to the console ("TYPE tmp_file" method) ; Default color - Bright Yellow on Black background Local $h, $sTmpFn = _TempFile(@ScriptDir) $h = FileOpen($sTmpFn, $FO_BINARY + $FO_OVERWRITE) If $h < 0 Then Return ConsoleWrite($sTxt) If Not FileWrite($h, Chr(27) & "[" & $iFg1 & "m" & Chr(27) & _ "[" & $iBg1 & "m" & $sTxt & Chr(27) & "[" & $iFg0 & "m" & _ Chr(27) & "[" & $iBg0 & "m") Then FileClose($h) Return ConsoleWrite($sTxt) EndIf FileClose($h) _RunDos("type " & $sTmpFn) FileDelete($sTmpFn) EndFunc ;==>_ConsoleWriteANSI Func _CreateDir($sDirName, $sLabel = $sDirName) Local $sMsg = "" If Not FileExists($sDirName) Then If Not DirCreate($sDirName) Then _CleanUp() _ConsoleEraseLine(50) $sMsg = "Error creating " & $sLabel & "!" If $sDirName <> $sLabel Then $sMsg &= "[" & $sDirName & "]" _ConsoleWriteANSI($sMsg & @CRLF, 96, 40) Exit 2 EndIf EndIf Return EndFunc ;==>_CreateDir Func _ExitErr($sMg) Exit ConsoleWrite($sMg & @CRLF) EndFunc ;==>_ExitErr Func _LogEntry($sStatus) If Not $sStatus Then Return Local $h1, $h2, $sFC = "", $bFN = 0 Local $sEntry = @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & _ ":" & @MIN & ":" & @SEC & @CRLF & "Remote file: " & $sRemoteFn & _ @CRLF & "Local file: " & $sLocalFn & @CRLF & "Status: " & _ $sStatus & @CRLF & @CRLF If Not FileExists($sLogFile) Then If Not _FileCreate($sLogFile) Then Return $bFN = 1 EndIf If Not $bFN Then $h1 = FileOpen($sLogfile, $FO_READ) If $h1 > -1 Then $sFC = FileRead($h1) FileClose($h1) Else Return EndIf EndIf $sFC = $sEntry & $sFC $h2 = FileOpen($sLogfile, $FO_OVERWRITE) If $h2 > -1 Then FileWrite($h2, $sFC) FileClose($h2) Else Return EndIf EndFunc ;==>_LogEntry Func _ShowHelp() _ConsoleWriteANSI(@ScriptName & " " & $sRevDate & @CRLF & "File Updater for the Windows Command Line" & @CRLF) ConsoleWrite(@ScriptName & " compares a local file to a remote file; if the" & @CRLF & "two files' contents are not identical, the local file is" & @CRLF & "first backed up (to <filename>-<YYMMDD>T<hhmmss>[.<ext>]) and" & @CRLF & "then overwritten (updated) with the contents of the remote file." & @CRLF & "How It Works: " & @ScriptName & " compares SHA256 hashes of the local and" & @CRLF & "remote files. If the hashes differ, or if the local file does" & @CRLF & "not exist, an update is triggered." & @CRLF & "---" & @CRLF) _ConsoleWriteANSI("The first time you run " & @ScriptName & ", it will create the text file" & @CRLF, 96, 40) _ConsoleWriteANSI(" >>> " & $sIniFile & " <<<" & @CRLF, 97, 40) _ConsoleWriteANSI( "and open it in Notepad. To use " & @ScriptName & ", you must add one or " & @CRLF & "more ", 96, 40) _ConsoleWriteANSI("[Sections]", 97, 40) _ConsoleWriteANSI(" to " & $sIniFile & ", supplying ""LocalFile""" & @CRLF & "and ""RemoteFile"" values for each file you wish to update." & @CRLF, 96, 40) ConsoleWrite("---" & @CRLF) _ConsoleWriteANSI("Command-Line Usage:" & @CRLF, 97, 40) ConsoleWrite(" Updater.exe [/L[[:]<LogFileName>]] [/Q[Q] [<IniSectionName>] | /?" & @CRLF & "Do NOT put square brackets ""[]"" around <IniSectionName>" & @CRLF & "If <IniSectionName> is omitted, the file identified in .ini" & @CRLF & " section ""[Default]"" (if any) is checked for updates" & @CRLF & "Option /L[[:]<LogFileName>] logs update status;" & @CRLF & " Default LogFileName = " & StringTrimRight(@ScriptName, 4) & ".log" & @CRLF & " Newest entry is at top of file" & @CRLF & "Option /Q (""Quiet"") suppresses informational prompts" & @CRLF & "Option /QQ (""very Quiet"") also suppresses error messages" & @CRLF & "Option /? displays this help" & @CRLF & "Demo: Command ") _ConsoleWriteANSI(@ScriptName & " DEMO", 96, 40) ConsoleWrite(" to ""update"" a throwaway file" & @CRLF) EndFunc ;==>_ShowHelp Edited August 13 by CarlD Added "How It Works" to help (/?); use ver. 2024-08-13 mLipok 1 Link to comment Share on other sites More sharing options...
CarlD Posted August 10 Author Share Posted August 10 Latest revision features an .ini file which allows Updater to be used for multiple different file updates. The first time you run Updater.exe, it creates Updater.ini and opens it for editing in Notepad. User is prompted to add a new [Section] for each a local-remote file pair. The command-line usages is now Updater.exe section_name. Link to comment Share on other sites More sharing options...
CarlD Posted August 11 Author Share Posted August 11 Configuration variables BaseURL and RemoteFile merged into RemoteFile. Other small and large-ish fixes. Link to comment Share on other sites More sharing options...
CarlD Posted August 13 Author Share Posted August 13 (edited) Ver. 2024-08-13 help summary Edited August 13 by CarlD Added "How It Works to help (/?) Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now