Old 3rd November 2008, 04:48   #1
hinmanj
Junior Member
 
Join Date: Nov 2008
Posts: 3
Find size of file before downloading?

I'm using NSISdl to download files remotely, and I would love to know how to find the size of a file out before downloading, so when on the components page I know how big a component is. I wish I could do something like AddSize 5000 or whatever, but I since the installer doesn't download the file until after the components page, I can't check for the file size on the system.

Is there a built in function in NSISdl or another plugin that could allow this? I've looked around the internet functions in the Developer Center and came up empty handed, any help would be greatly appreciated!
hinmanj is offline   Reply With Quote
Old 3rd November 2008, 13:44   #2
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,366
i'm using curl to do so, though it's the most elegant solution maybe and it might not work with all servers
Yathosho is offline   Reply With Quote
Old 3rd November 2008, 19:07   #3
Takhir
Major Dude
 
Join Date: Feb 2004
Location: Moscow, Russia
Posts: 1,222
http://nsis.sourceforge.net/Inetc_pl...d_DLL_Function
Takhir is offline   Reply With Quote
Old 3rd November 2008, 21:13   #4
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Just to expand a little on what Takhir means - you can use inetc:head to get just the headers off of the server. This -should- contain the size of the file.. but always check..some servers do not provide this information in the headers;
if you've ever tried downloading a file and it can't tell you how far along it is in its download / how much longer it will take, it's because the server did not provide that information.
Animaether is offline   Reply With Quote
Old 4th November 2008, 04:49   #5
hinmanj
Junior Member
 
Join Date: Nov 2008
Posts: 3
Hmm... so I'd have to call inetc::head and then parse through the file that it outputs for the Content-Length and then AddSize that? ugh... I haven't done any file parsing in NSIS and wouldn't have the slightest idea where to begin.
hinmanj is offline   Reply With Quote
Old 5th November 2008, 19:02   #6
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
it's not so bad, hinmanj - here's a quick example script:

code:

!define DOWNLOAD_URL "http://www.google.com/intl/en_ALL/images/logo.gif"

; inetc.dll in the same folder as the source script.
; can remove this line if you've got it in NSIS\Plugins
!addplugindir "."

OutFile "content-length_test.exe"

Section
inetc::head /TIMEOUT 10000 ${DOWNLOAD_URL} "$EXEDIR\http.headers"
Pop $0
StrCmp $0 "OK" _ok
_error:
MessageBox MB_OK "Could not download."
goto _end
_ok:
StrCpy $R0 -1
FileOpen $0 "$EXEDIR\http.headers" "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: $R0 bytes"
_end:
SectionEnd

Animaether is offline   Reply With Quote
Old 23rd June 2010, 13:40   #7
Grytolle
Junior Member
 
Join Date: Jun 2010
Posts: 9
The above code example worked great for me, but now I realize that it detects the compressed size of my remote zip-files. Could anyone tell me how to detect the unzipped size without downloading the file, or is that not possible?

I turned Animaether's code into a macro, perhaps it could be of use to other beginners like me too:

code:
Usage: !insertmacro SetRemoteFileSize section url-of-remote-file

!macro SetRemoteFileSize sectie bestand
inetc::head /TIMEOUT 10000 ${bestand} "$EXEDIR\http.headers"
Pop $0
StrCmp $0 "OK" _ok${sectie} _error${sectie}
_error${sectie}:
MessageBox MB_OK "Non-fatal error! Could not detect file size of remote media $\"${sectie}$\"."
goto _end${sectie}
_ok${sectie}:
StrCpy $R0 -1
FileOpen $0 "$EXEDIR\http.headers" "r"
_nextline${sectie}:
ClearErrors
FileRead $0 $1
IfErrors _closeFile${sectie}
StrCpy $2 $1 16
StrCmp $2 "Content-Length: " _found${sectie} _nextline${sectie}
_found${sectie}:
StrCpy $R0 $1 "" 16
goto _closeFile${sectie}
_closeFile${sectie}:
FileClose $0
IntOp $R0 $R0 / 1024 ;SectionSize requires kilobytes
SectionSetSize ${${sectie}} $R0
_end${sectie}:
!macroend


Grytolle is offline   Reply With Quote
Old 23rd June 2010, 13:43   #8
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
You need to provide that information yourself; perhaps include a plain text file with the same name as the compressed file and download that first.

Stu
Afrow UK is offline   Reply With Quote
Old 23rd June 2010, 13:52   #9
Grytolle
Junior Member
 
Join Date: Jun 2010
Posts: 9
Alright, that's what I feared. One of the files is hosted on a host of mine, so I could easily put together a little php-script for this purpose. The other one is not, but perhaps I can persuade the maker to provide that information somewhere.

Anyway, thanks for your help!
Grytolle is offline   Reply With Quote
Old 23rd June 2010, 13:54   #10
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
Unless that information is stored in the header of the Zip file itself you'd need to decompress the Zip file to find out the uncompressed size - maybe a one time PHP script that does it and writes your text file.

Stu
Afrow UK is offline   Reply With Quote
Old 23rd June 2010, 14:52   #11
Grytolle
Junior Member
 
Join Date: Jun 2010
Posts: 9
Yes

Edit: here's my solution

Create a new php file in the same folder as the file that is to be downloaded:
code:
<?php
$totalsize=0;
$zip = zip_open($saveToDir."something.zip");
while($z = zip_read($zip)) {
$totalfilesize += zip_entry_filesize($z);
}
zip_close($zip);
echo "UnzippedLength: ".$totalfilesize;
?>



Modified code to retrieve the generated string by the php-file:
code:
!addplugindir "."
RequestExecutionLevel user
OutFile "content-length_test.exe"

Section
NSISdl::download_quiet "YOUR URL.php" "$EXEDIR\filesize-za.txt"
Pop $0
StrCmp $0 "success" _ok
MessageBox MB_OK "Could not download."
goto _end
_ok:
StrCpy $R0 -1
FileOpen $0 "$EXEDIR\filesize-za.txt" "r"
_nextline:
ClearErrors
FileRead $0 $1
IfErrors _closeFile
StrCpy $2 $1 16
StrCmp $2 "UnzippedLength: " _found _nextline
_found:
StrCpy $R0 $1 "" 16
goto _closeFile
_closeFile:
FileClose $0
IntOp $R0 $R0 / 1024 ;bytes -> kilobytes
MessageBox MB_OK "retrieved unzipped size: $R0 KB"
Delete "$EXEDIR\filesize-za.txt"
_end:
SectionEnd


Last edited by Afrow UK; 24th June 2010 at 20:04. Reason: Adding solution; removed duplicate zip_entry_filesize() call
Grytolle is offline   Reply With Quote
Old 24th June 2010, 10:45   #12
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
Just a thought: You might as well remove the if(zip_entry_filesize($z)==0) continue; line. Quicker to add 0 than to call zip_entry_filesize() twice.

Stu
Afrow UK is offline   Reply With Quote
Old 24th June 2010, 14:46   #13
Grytolle
Junior Member
 
Join Date: Jun 2010
Posts: 9
Good point. I can't seem to edit the code above though
Grytolle is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump