novocaine
21st February 2009 15:02 UTC
file check and download with nsis
hi everyone
i need to know if with nsis is possible to create an updater with this features:
1) Check where a program is installed (done with InstallDirRegKey)
2) Check a list of files already installed on the pc with filesize or crc check and:
if the files has a different CRC or filesize from other files stored in a webserver: delete old file, download it from the server and add the new one;
else if is up to date skip.
suggestions?
i have read some threads and the documentation of nsis, but i get a lot confused :cry:
thanks in advance for your help[list=1][/list=1]
Animaether
21st February 2009 20:48 UTC
is your question...
A. Can I do this?
B. Can you point me to some ways to do this?
C. Can you write this for me?
Because...
A. yes
B. Sure...
-- registry --
InstallDirRegKey - that only really applies to your own installer. If it is your own installer, that's fine. Otherwise, look into ReadRegStr to read a string from a registry key value.
-- getting a file list --
You can use the FindFirst, FindNext and FindClose methods to loop over files, or you can use one of the many pre-made loop-over-files functions here:
nsis.sourceforge.net/Category:Disk,_Path_&_File_Functions
-- CRC / MD5 --
I would go with an MD5, as that has become the defacto standard for hashing a file.
http://nsis.sourceforge.net/MD5_plugin
You can extend that, for some additional checking, with the size of the file using GetSize from FileFunc.nsh (included with NSIS, just !include `FileFunc.nsh` - see documentation). You can also do this yourself by opening the file, seeking to its end, and then getting the position, then closing the file.
== Get file data from website / Download new files ==
Use a plugin such as inetc..
http://nsis.sourceforge.net/Inetc_plug-in
..to download a text file that has the information on the current files (i.e. which files should be present, which are old and should be deleted, and their MD5 hashes).
Read that text file, compare to your findings from the above (i.e. check the MD5 by comparing the strings). IIf the files differ, back the old file up and use inetc again to download the new file. If that download fails, you may wish to restore the old file. (or, better, download to a temporary file and only backup/delete the old file if the download was successful).
Done.
It *is* a bit of work, but it's certainly doable :)
C. what's your offer? ;)
(kidding - what spare time I have I'm trying to spend away from code where I can)
novocaine
21st February 2009 21:25 UTC
fisrt of all, thank you for your reply
i have started to work and i'mk in a good point, but i have a problem.
how can i check the md5 of the files stored in the webserver?
and how can i confront with those are alredy insalled?
edit: maybe i have found a solution..
Red Wine
21st February 2009 22:06 UTC
edit: maybe i have found a solution..
you're enigmatic...
tell us about the solution.
novocaine
21st February 2009 22:55 UTC
Section "Client" client
;file nel server
inetc::head /TIMEOUT 10000 "http://www.xxx.com/nhr/Client.exe" "$TEMP\client.exe"
Pop $0
StrCmp $0 "OK" _ok
_error:
MessageBox MB_OK "Could not download."
goto _end
_ok:
StrCpy $R0 -1
FileOpen $0 "$TEMP\client.exe" "r"
_nextline:
ClearErrors
FileRead $0 $1
IfErrors _closeFile
StrCpy $2 $1 16
StrCmp $2 "Content-Length: " _found _nextline
_found:
StrCpy $R0 $1 "" 16
goto _closeFile
_closeFile:
FileClose $0
MessageBox MB_OK "File size web: $R0"
_end:
;file presente nel pc
${GetSize} "$INSTDIR" "/M=client.exe /S=0b /G=0" $0 $1 $2
MessageBox MB_OK "File size pc: $0"
MessageBox MB_OK "File size: $R0 - $0"
;confronto i files
${if} $0 == $R0
MessageBox MB_OK "Il file client è giÃ_ aggiornato!"
ABORT
${else}
; single file, NSISdl-style embedded progress bar with specific cancel button text
inetc::get /caption "2005 report" /canceltext "Annulla" "http://www.xxx.com/nhr/Client.exe" "$INSTDIR\client.exe" /end
Pop $0 # return value = exit code, "OK" means OK
${endif}
sectionend
why doesn't work :cry:
EDIT: ok now i can check both sizes of files but the if is not working -.-
demiller9
22nd February 2009 04:10 UTC
== is a string comparison, = is a signed integer comparison operator. Your registers (especially $R0) might contain more than just digits and the strings might not match even though the values do. Try using the = operator instead of the ==.
Don
novocaine
22nd February 2009 10:11 UTC
thank you it works, scripting in php makes really different :P