Jump to content

Best way to check for updated file on server?


RickB75
 Share

Recommended Posts

@guinness

The _VersionCompare is awesome. Thanks for mentioning!!

No problem.

This is what I meant. If you have a file which is 20MB, then you have to download everytime, where as my example will check the modified date on the server against the created date of the script.

#include <FileConstants.au3>
#include <WinHTTP.au3>

Example()

Func Example()
    ; Open the handles.
    Local Const $hOpen = _WinHttpOpen()
    Local Const $hConnect = _WinHttpConnect($hOpen, 'www.autoitscript.com') ; Connect to the hostname.
    Local $hRequest = _WinHttpOpenRequest($hConnect, 'HEAD', '/autoit3/mvps/guinness/file.txt') ; Filepath.

    ; Send a request.
    _WinHttpSendRequest($hRequest)

    ; Wait for a response.
    _WinHttpReceiveResponse($hRequest)

    ; Check if the status code was OK aka 200.
    Local $bIsStatusOK = Int(_WinHttpQueryHeaders($hRequest, $WINHTTP_QUERY_STATUS_CODE)) = $HTTP_STATUS_OK

    ; If we got a 'good' response form the server.
    If $bIsStatusOK Then
        ; Some weird format is returned from the server most likely.
        Local $sNewModifiedDate = _WinHttpQueryHeaders($hRequest, $WINHTTP_QUERY_LAST_MODIFIED)

        ; Get the created time of this script file.
        Local $sCurrentModifiedDate = FileGetTime(@ScriptFullPath, $FT_CREATED, 1)

        ; Parse into something we can recognise e.g. yyyymmddhhmmss
        Local $aDateTime = _WinHttpTimeToSystemTime($sNewModifiedDate)
        If @error Then
            $sNewModifiedDate = $sCurrentModifiedDate ; If an error occurred then set to the current date and time.
        Else
            Local Enum $INET_TIME_YEAR, $INET_TIME_MONTH, $INET_TIME_DAY = 3, $INET_TIME_HOUR, $INET_TIME_MINUTES, $INET_TIME_SECONDS ; Constants so I don't have to use 'magic numbers' for the array indexers.
            For $i = $INET_TIME_MONTH To $INET_TIME_SECONDS
                $aDateTime[$i] = StringRight('0' & $aDateTime[$i], 2) ; Format to double digits for months, days, hours, minutes and seconds. It pre-appends a zero and extracts the 2 right mosts chars.
            Next
            $sNewModifiedDate = $aDateTime[$INET_TIME_YEAR] & $aDateTime[$INET_TIME_MONTH] & $aDateTime[$INET_TIME_DAY] & $aDateTime[$INET_TIME_HOUR] & $aDateTime[$INET_TIME_MINUTES] & $aDateTime[$INET_TIME_SECONDS]
        EndIf

        ConsoleWrite('The modified date of the file on the server was; ' & $sNewModifiedDate & @CRLF)
        If Not ($sCurrentModifiedDate == $sNewModifiedDate) Then ; You could use _DateDiff(), but I am just doing a straight comparison.
            ConsoleWrite('The file on the sever has a different modified date.' & @CRLF)
        Else
            ConsoleWrite('The file dates are the same.' & @CRLF)
        EndIf
    EndIf

    ; Close the handles.
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)
EndFunc   ;==>Example
Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

  • 2 months later...

I handle mine from a web server, but slight modification can use FTP for the actual download.

I have a folder below my web root called 'updates' that has folders for each of my compiled scripts that need updating.

Each script folder has an 'index.html' file with nothing but the file version of the exe, and the exe itself.

I call _CheckForUpdate(), and let the magic happen.

Func _CheckForUpdate()
    If Not @Compiled Then Return -1
    Local $CurVer = StringSplit(FileGetVersion(@ScriptFullPath), ".", 2)
    Local $UpdateSource = _CheckForUpdatePath()
    If $UpdateSource = "" Then Return
    Local $er
    Local $i
    Local $newer = False
    Local $AvailVer = StringSplit(BinaryToString(InetRead($UpdateSource, 16+1)), ".", 2)
    For $i = 0 To 3
        If $AvailVer[$i] > $CurVer[$i] Then
            $newer = True
            ExitLoop
        ElseIf $AvailVer[$i] < $CurVer[$i] Then
            ExitLoop
        EndIf
    Next

    If $newer Then
        $er = 1
        InetGet($UpdateSource & "/" & $MyName & ".exe", @ScriptDir & "/" & $MyName & ".exe_", 1+8+16, 0)
        If @error Then $er -= 1
        Sleep(5000)
        If Not FileExists(@ScriptDir & "/" & $MyName & ".exe_") Then $er -= 1
        If $er < 1 Then Return
        FileInstall("stub.exe",@ScriptDir & "\stub.exe",1)
        Run(@ScriptDir & "\stub.exe " & $MyName,@ScriptDir, @SW_HIDE)
        Exit
    EndIf
EndFunc

Func _CheckForUpdatePath()
    Local $i, $AvailVer
    Local $UpdateSources[4] = ["http://server1/updates/" & $MyName, _
                               "http://server2/updates/" & $MyName, _
                               "http://server3/updates/" & $MyName, _
                               "http://www.externalserver.com/updates/" & $MyName]
    For $i = 0 to UBound($UpdateSources)-1
        $AvailVer = StringSplit(BinaryToString(InetRead($UpdateSources[$i], 16+1)), ".", 2)
        If UBound($AvailVer)=4 Then Return $UpdateSources[$i]
    Next
    Return ""
EndFunc

$MyName is set to @ScriptName, less the extension.

Stub.exe is a small script that handles killing the running exe (since you can't replace it while it is running), swapping it out, and relaunching the new one.

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