stopasking
28th November 2011 16:13 UTC
[Solution] Getting file size at compile time
Hi guys.
I managed to solve my previous issue, here's the code I came up with to get a size of file at compile time:
!macro CTFileSize _FILE _RESULT
!echo 'CTFileSize: "${_FILE}"'
!verbose push
!verbose 3
!tempfile __TEMP_BAT_FILE
!delfile "${__TEMP_BAT_FILE}"
!tempfile __TEMP_NSH_FILE
!delfile "${__TEMP_NSH_FILE}"
!system 'cmd /C ECHO @ECHO Push %~z1 > "${__TEMP_BAT_FILE}.bat"'
!system '"${__TEMP_BAT_FILE}.bat" "${_FILE}" > "${__TEMP_NSH_FILE}.nsh"'
!include "${__TEMP_NSH_FILE}.nsh"
!delfile "${__TEMP_BAT_FILE}.bat"
!undef __TEMP_BAT_FILE
!delfile "${__TEMP_NSH_FILE}.nsh"
!undef __TEMP_NSH_FILE
Pop ${_RESULT}
!verbose pop
!macroend
Usage:
!insertmacro CTFileSize "C:\Windows\notepad.exe" $R0
MessageBox MB_OK "Size of notepad: $R0 bytes"
Perhaps somebody else will find it useful.
P.S. I use this code to calculate the size of a section for several install modes, and change it at runtime, using the SectionSetSize function.
The docs say:
"The Value for Size must be entered in KiloByte and supports only whole numbers."
Only whole KBs? Why the heck is that? o_0
MSG
28th November 2011 17:06 UTC
Whole KBs is probably to allow larger sizes within a 32 bits variable.
Next time, please post the solution in the thread where you asked the question.
Anders
28th November 2011 17:19 UTC
Why post a new thread?
My take on this:
!macro GetFileSize define file
!tempfile __GetFileSize
!execute 'cmd /E:ON /V:OFF /C if 1==1 for %A in ("${file}") do echo !define ${define} "%~zA" > "${__GetFileSize}"'
!include "${__GetFileSize}"
!delfile "${__GetFileSize}"
!undef __GetFileSize
!macroend
!insertmacro GetFileSize thesize "$%windir%\explorer.exe"
!echo thesize=${thesize}
Edit: Added missing !undef
stopasking
28th November 2011 18:12 UTC
Next time, please post the solution in the thread where you asked the question.
OK, sorry, I just thought that it would be easier for others to find it that way. (SEO, page title, etc.)
Also, maybe it's worth to add this to the wiki?
Whole KBs is probably to allow larger sizes within a 32 bits variable.
More than 4 GB for an installer?
I don't think so (I bet it won't work anyway).
If you know another way of e.g. setting a section size in bytes and not in KBs, tell me. It's not a must but it looks nicer. After all, NSIS does that by default.
My take on this
Wow, nice! :)
I'm not too good at working with cmd, so I would never come up with this.
A couple of corrections, though:
* A "/Q" parameter for cmd to turn off echo.
* What is the "if 1==1" for? I guess nothing.
* You forgot to undef __GetFileSize.
Also, it's more convenient for me to get the size to a variable, and not to a define, so here's my version:
!macro CTFileSize _FILE _RESULT
!tempfile __TEMP_NSH_FILE
!execute 'cmd /Q /E:ON /V:OFF /C for %A in ("${_FILE}") do echo StrCpy ${_RESULT} %~zA > "${__TEMP_NSH_FILE}"'
!include "${__TEMP_NSH_FILE}"
!delfile "${__TEMP_NSH_FILE}"
!undef __TEMP_NSH_FILE
!macroend
Usage is the same as in the first post:
!insertmacro CTFileSize "C:\Windows\notepad.exe" $R0
MessageBox MB_OK "Size of notepad: $R0 bytes"
Anders
28th November 2011 18:16 UTC
IF 1==1 does "nothing" yes, but it fixes bugs in cmd.exe
stopasking
28th November 2011 18:32 UTC
That's interesting, what bugs does it fix?
MSG
28th November 2011 18:57 UTC
Originally posted by stopasking
More than 4 GB for an installer?
I don't think so (I bet it won't work anyway).
I have one. CopyFiles and AddSize are your friends.
stopthemess
14th December 2012 14:49 UTC
I need to get a size of a folder at compile time.
I came up with the following batch script:
@ECHO OFF
SET sum=0
FOR /R %1 %%A IN (*) DO ( SET /A sum+=%%~zA )
echo %sum%
It works.
Now I want to use it as a command line parameter of cmd.
I tried the following:
cmd /Q /E:ON /V:OFF /K SET sum=0 & FOR /R "%userprofile%\Desktop\" %A IN (*) DO ( SET /A sum+=%~zA ) & ECHO %sum%
but it doesn't work as expected.
Help me please.
--EDIT--
That's what I came up with:
!macro CTFolderSize _FOLDER _RESULT
!tempfile __TEMP_NSH_FILE
!execute 'cmd /Q /E:ON /V:OFF /C (SET sum=0) & (FOR /R "${_FOLDER}" %A IN (*) DO SET /A "sum+=%~zA" > NUL ) & ( CALL ECHO StrCpy ${_RESULT} %sum% > "${__TEMP_NSH_FILE}" )'
!include "${__TEMP_NSH_FILE}"
!delfile "${__TEMP_NSH_FILE}"
!undef __TEMP_NSH_FILE
!macroend
I'm not sure how good is the solution, but it seems to work.