Calculating Space required
Is there any way to calculate the Space Required for installation?
5 posts
The function for the Browse button is as follows, in case you can use it:Function DIRECTORYpage
nsDialogs::Create /NOUNLOAD 1018
Pop $2
GetDlgItem $1 $HWNDPARENT 1
EnableWindow $1 0
${NSD_CreateLabel} 0u 0u 300u 18u "Setup will install $(^Name) in the following folder. \
To install in a different folder, click Browse and select \
another folder. Click Next to continue."
Pop $2
${NSD_CreateGroupBox} 0u 70u 300u 35u "Destination Folder"
Pop $2
${NSD_CreateDirRequest} 10u 85u 210u 12u "$INSTDIR"
Pop $NSDFIELD1
${NSD_OnChange} $NSDFIELD1 DIRECTORYField1
${NSD_CreateBrowseButton} 229u 83u 59u 15u "Br&owse..."
pop $NSDBUTTON1
${NSD_OnClick} $NSDBUTTON1 DIRECTORYButton1
${NSD_CreateLabel} 0u 115u 100u 10u "Space required: 0MB"
pop $NSDFIELD2
${NSD_CreateLabel} 0u 125u 100u 10u "Space available: 0MB"
pop $NSDFIELD3
call DIRECTORYField1
SendMessage $NSDFIELD1 ${EM_SETSEL} 0 -1
${NSD_SetFocus} $NSDFIELD1
!insertmacro MUI_HEADER_TEXT "Choose Install Location" "Choose the folder in which to install $(^Name)."
nsDialogs::Show
FunctionEnd
Function DIRECTORYField1
System::Call 'user32::GetWindowText(i $NSDFIELD1, t.r0, i${NSIS_MAX_STRLEN})'
StrCpy $1 $0 2 1
${If} $1 == ":\"
StrCpy $1 $0 2
System::Call 'kernel32::GetDiskFreeSpaceExA(t, *l, *l, *l)i(r1,.r2,.,.) .r3'
${If} $3 == 0
;could not detect free space, drive probably doesn't exist. Disable Next button.
SendMessage $NSDFIELD2 ${WM_SETTEXT} 0 "STR:Space required: 0MB"
GetDlgItem $1 $HWNDPARENT 1
EnableWindow $1 0
goto DIRECTORYField1end
${EndIf}
StrCpy $INSTDIR $0
#(call some function that computes how much space is
# needed, depending on what files were found in $INSTDIR)
Math::Script 'r1 = ff(f(r2)/1048576,17); #[r1 > 999, r1 = ff(r1/1024,17) + "GB", r1 = r1 + "MB"]'
SendMessage $NSDFIELD3 ${WM_SETTEXT} 0 "STR:Space available: $1"
Math::Script 'r1 = ff(f($SPACENEEDED)/1048576,17); #[r1 > 999, r1 = ff(r1/1024,17) + "GB", r1 = r1 + "MB"]'
SendMessage $NSDFIELD2 ${WM_SETTEXT} 0 "STR:Space required: $1"
;Prevent installing to root of $WINDIR, $WINDIR itself,
;$PROGRAMFILES or $SYSDIR (put down here because the
;Space fields should still update)
StrCpy $0 $INSTDIR 3
StrCpy $3 $WINDIR 3
${If} $0 == $3
${OrIf} $INSTDIR == "$PROGRAMFILES"
${OrIf} $INSTDIR == "$WINDIR"
${OrIf} $INSTDIR == "$SYSDIR"
GetDlgItem $1 $HWNDPARENT 1
EnableWindow $1 0
goto GetINSTDIRField1end
${EndIf}
Math::Script '#[$2 > $SPACENEEDED, r1 = "EnoughSpace"]'
${If} $1 == "EnoughSpace"
GetDlgItem $1 $HWNDPARENT 1
EnableWindow $1 1
${Else}
GetDlgItem $1 $HWNDPARENT 1
EnableWindow $1 0
${EndIf}
${Else}
SendMessage $NSDFIELD2 ${WM_SETTEXT} 0 "STR:Space required: 0MB"
GetDlgItem $1 $HWNDPARENT 1
EnableWindow $1 0
${EndIf}
DIRECTORYField1end:
FunctionEnd
And this uses the following macro:Function DIRECTORYButton1
;remove all trailing backslashes and spaces from $INSTDIR
StrCpy $2 $INSTDIR
StrCpy $1 $2 1 -1
StrCmp $1 '\' +2
StrCmp $1 ' ' 0 +3
StrCpy $2 $2 -1
goto -3
;Get the deepest existing subdirectory in $INSTDIR
${Do}
IfFileExists "$2\*.*" 0 +2
${ExitDo}
${CutBeforeLastBackslash} 3 $2
StrLen $1 $3
${If} $1 > 2
StrCpy $2 $3
${Else}
${ExitDo}
${EndIf}
${Loop}
nsDialogs::SelectFolderDialog "Select folder" $2
pop $3
StrCmp $3 "error" +2
StrCpy $INSTDIR $3
SendMessage $NSDFIELD1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
FunctionEnd
; Cut off a string just before its last backslash.
; _outvar is the number/name of the variable to write to (0 for $0, 2 for $2,
; NEVER USE $R# REGISTERS), _input is any string.
; Example:
;
; StrCpy $2 "c:\program files\longpath\subdir"
; ${CutBeforeLastBackslash} 3 $2
; # $2 is now: c:\program files\longpath\subdir
; # $3 is now: c:\program files\longpath
!macro _CutBeforeLastBackslash _outvar _input
Push $R0
Push $R1
Push $R2
!define Lprefix L${__LINE__}
StrCpy $R0 ${_input}
${Do}
StrLen $R2 $R0
${If} $R2 == "0"
${ExitDo}
${EndIf}
StrCpy $R1 $R0 "" -1
StrCpy $R0 $R0 -1
${If} $R1 == "\"
${ExitDo}
${EndIf}
${Loop}
StrCpy $${_outvar} $R0
!undef Lprefix
Pop $R2
Pop $R1
Pop $R0
!macroend
!define CutBeforeLastBackslash `!insertmacro _CutBeforeLastBackslash`