Get size on disk: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(Size On Disk (SOD) utility to get the space used by directories and files)
(Size On Disk (SOD) utility to get the space used by directories and files)
Line 13: Line 13:
!include "${LOCAL}macros.nsh"
!include "${LOCAL}macros.nsh"
ReserveFile "${NSISDIR}\Plugins\Math.dll"
ReserveFile "${NSISDIR}\Plugins\Math.dll"
#Icon "${LOCAL}arrows.ico"
Icon "${LOCAL}arrows.ico"
ShowInstDetails show
ShowInstDetails show


; Variables
; Variables
Var NSIS
Var NSIS
Var ZIP
Var ZIP_UN
Var COUNT
Var COUNT
Var BLOCK
Var BLOCK
Line 81: Line 79:
   begin:
   begin:
   IfFileExists "$NSIS" 0 done
   IfFileExists "$NSIS" 0 done
  ${GetFileAttributes} "$NSIS" "COMPRESSED" $ZIP
   ${GetClusterSize} $BLOCK
   ${GetClusterSize} $BLOCK
   ${GetSizeOnDisk} "$NSIS" "/S=0B" "" $0 $1 $2
   ${GetSizeOnDisk} "$NSIS" "/S=0B" "" $0 $1 $2
Line 96: Line 93:
; uninstaller
; uninstaller
   IfFileExists "$NSIS\uninst-nsis.exe" 0 done
   IfFileExists "$NSIS\uninst-nsis.exe" 0 done
  ${GetFileAttributes} "$NSIS\uninst-nsis.exe" "COMPRESSED" $ZIP_UN
   ${GetSizeOnDisk} "$NSIS" "/M=uninst-nsis.exe /S=0B" "" $0 $1 $2
   ${GetSizeOnDisk} "$NSIS" "/M=uninst-nsis.exe /S=0B" "" $0 $1 $2
   Math::Script "r6 = ff($0 / 1024.0, 16 +1); \
   Math::Script "r6 = ff($0 / 1024.0, 16 +1)"
  a = $0; b = $BLOCK; c = a % b; #[c == 0, c = $BLOCK]; r7 = (b - c + a); \
  r8 = ff(r7 / 1024.0, 16 +1)"
   StrCpy $SIZE_UN_B $0
   StrCpy $SIZE_UN_B $0
   StrCpy $SIZE_UN_K $6
   StrCpy $SIZE_UN_K $6
   StrCpy $SOD_UN_B $7
  ${GetSizeOnDisk} "$NSIS" "/M=uninst-nsis.exe /S=0B" "$BLOCK" $0 $1 $2
   StrCpy $SOD_UN_K $8
  Math::Script "r7 = ff($0 / 1024.0, 16 +1)"
   StrCpy $SOD_UN_B $0
   StrCpy $SOD_UN_K $7
; format
; format
   StrCpy $R1 $SIZE_B
   StrCpy $R1 $SIZE_B
Line 125: Line 121:
   StrCpy $SOD_UN_B $R2
   StrCpy $SOD_UN_B $R2
; output
; output
  ; note: with compression SOD lines are incorrect
   DetailPrint ""
   DetailPrint ""
   DetailPrint "$NSIS"
   DetailPrint "$NSIS"
   DetailPrint "Size: $SIZE_M MB ($SIZE_B bytes)"
   DetailPrint "Size: $SIZE_M MB ($SIZE_B bytes)"
  StrCmp $ZIP "1" +3
  StrCmp $ZIP_UN "1" +2
   DetailPrint "SOD: $SOD_M MB ($SOD_B bytes)"
   DetailPrint "SOD: $SOD_M MB ($SOD_B bytes)"
   DetailPrint ""
   DetailPrint ""
   DetailPrint "Uninstaller"
   DetailPrint "Uninstaller"
   DetailPrint "Size: $SIZE_UN_K KB ($SIZE_UN_B bytes)"
   DetailPrint "Size: $SIZE_UN_K KB ($SIZE_UN_B bytes)"
  StrCmp $ZIP "1" +3
  StrCmp $ZIP_UN "1" +2
   DetailPrint "SOD: $SOD_UN_K KB ($SOD_UN_B bytes)"
   DetailPrint "SOD: $SOD_UN_K KB ($SOD_UN_B bytes)"
   DetailPrint ""
   DetailPrint ""
Line 152: Line 143:
You should copy the next code into a separate file: <b>macros.nsh</b>.
You should copy the next code into a separate file: <b>macros.nsh</b>.
<highlight-nsis>
<highlight-nsis>
; Macros include file
; Macros include (TN)
;--------------------------------
;--------------------------------
/*
/*


  FileFunction=[GetSizeOnDisk|GetClusterSize|GetFileAttributes]
  FileFunction=[GetSizeOnDisk|GetClusterSize]


*/
*/
Line 209: Line 200:
!verbose ${_FILEFUNC_VERBOSE}
!verbose ${_FILEFUNC_VERBOSE}
${CallArtificialFunction} GetClusterSize_
${CallArtificialFunction} GetClusterSize_
Pop ${_RESULT}
!verbose pop
!macroend
!macro GetFileAttributesCall _PATH _ATTR _RESULT
!verbose push
!verbose ${_FILEFUNC_VERBOSE}
Push `${_PATH}`
Push `${_ATTR}`
${CallArtificialFunction} GetFileAttributes_
Pop ${_RESULT}
Pop ${_RESULT}
!verbose pop
!verbose pop
Line 410: Line 391:
IntOp $R4 $R4 + 1
IntOp $R4 $R4 + 1
; insert code
; insert code
StrCmp $R1 "" +10 0
StrCmp $R1 "" FileFunc_GetSize_file_add
System::Call 'kernel32::GetFileAttributes(t "$R8\$R7")i .R2'
StrCmp $R2 -1 FileFunc_GetSize_file_logical
IntOp $R0 $R2 & 0x0800
IntCmp $R0 0 0 0 +3
IntOp $R0 $R2 & 0x0200
IntCmp $R0 0 FileFunc_GetSize_file_logical
System::Call 'kernel32::GetCompressedFileSize(t "$R8\$R7", i)i .R6'
IntCmp $R6 4096 FileFunc_GetSize_file_add 0 FileFunc_GetSize_file_add
StrCpy $R6 4096
goto FileFunc_GetSize_file_add
FileFunc_GetSize_file_logical:
StrCpy $R0 $R1
StrCpy $R0 $R1
IntOp $R6 $R6 + $R0
IntOp $R6 $R6 + $R0
Line 420: Line 412:
IntOp $R6 $R6 + $R2
IntOp $R6 $R6 + $R2
StrCpy $R1 $R0
StrCpy $R1 $R0
FileFunc_GetSize_file_add:
; end insert
; end insert
System::Int64Op $R3 + $R6
System::Int64Op $R3 + $R6
Line 497: Line 490:
Exch $1
Exch $1
Exch 2
Exch 2
Exch $0
!verbose pop
!macroend
; ---------------
; GetFileAttributes (FileFunc.nsh)
!define GetFileAttributes `!insertmacro GetFileAttributesCall`
!define un.GetFileAttributes `!insertmacro GetFileAttributesCall`
!macro GetFileAttributes
!macroend
!macro un.GetFileAttributes
!macroend
!macro GetFileAttributes_
!verbose push
!verbose ${_FILEFUNC_VERBOSE}
Exch $1
Exch
Exch $0
Exch
Push $2
Push $3
Push $4
Push $5
System::Call 'kernel32::GetFileAttributes(t r0)i .r2'
StrCmp $2 -1 FileFunc_GetFileAttributes_error
StrCpy $3 ''
IntOp $0 $2 & 0x4000
IntCmp $0 0 +2
StrCpy $3 'ENCRYPTED|'
IntOp $0 $2 & 0x2000
IntCmp $0 0 +2
StrCpy $3 'NOT_CONTENT_INDEXED|$3'
IntOp $0 $2 & 0x1000
IntCmp $0 0 +2
StrCpy $3 'OFFLINE|$3'
IntOp $0 $2 & 0x0800
IntCmp $0 0 +2
StrCpy $3 'COMPRESSED|$3'
IntOp $0 $2 & 0x0400
IntCmp $0 0 +2
StrCpy $3 'REPARSE_POINT|$3'
IntOp $0 $2 & 0x0200
IntCmp $0 0 +2
StrCpy $3 'SPARSE_FILE|$3'
IntOp $0 $2 & 0x0100
IntCmp $0 0 +2
StrCpy $3 'TEMPORARY|$3'
IntOp $0 $2 & 0x0080
IntCmp $0 0 +2
StrCpy $3 'NORMAL|$3'
IntOp $0 $2 & 0x0040
IntCmp $0 0 +2
StrCpy $3 'DEVICE|$3'
IntOp $0 $2 & 0x0020
IntCmp $0 0 +2
StrCpy $3 'ARCHIVE|$3'
IntOp $0 $2 & 0x0010
IntCmp $0 0 +2
StrCpy $3 'DIRECTORY|$3'
IntOp $0 $2 & 0x0004
IntCmp $0 0 +2
StrCpy $3 'SYSTEM|$3'
IntOp $0 $2 & 0x0002
IntCmp $0 0 +2
StrCpy $3 'HIDDEN|$3'
IntOp $0 $2 & 0x0001
IntCmp $0 0 +2
StrCpy $3 'READONLY|$3'
StrCpy $0 $3 -1
StrCmp $1 '' FileFunc_GetFileAttributes_end
StrCmp $1 'ALL' FileFunc_GetFileAttributes_end
FileFunc_GetFileAttributes_attrcmp:
StrCpy $5 0
IntOp $5 $5 + 1
StrCpy $4 $1 1 $5
StrCmp $4 '' +2
StrCmp $4 '|'  0 -3
StrCpy $2 $1 $5
IntOp $5 $5 + 1
StrCpy $1 $1 '' $5
StrLen $3 $2
StrCpy $5 -1
IntOp $5 $5 + 1
StrCpy $4 $0 $3 $5
StrCmp $4 '' FileFunc_GetFileAttributes_notfound
StrCmp $4 $2 0 -3
StrCmp $1 '' 0 FileFunc_GetFileAttributes_attrcmp
StrCpy $0 1
goto FileFunc_GetFileAttributes_end
FileFunc_GetFileAttributes_notfound:
StrCpy $0 0
goto FileFunc_GetFileAttributes_end
FileFunc_GetFileAttributes_error:
SetErrors
StrCpy $0 ''
FileFunc_GetFileAttributes_end:
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
!verbose pop
!macroend
!define GetFileVersion `!insertmacro GetFileVersionCall`
!define un.GetFileVersion `!insertmacro GetFileVersionCall`
!macro GetFileVersion
!macroend
!macro un.GetFileVersion
!macroend
!macro GetFileVersion_
!verbose push
!verbose ${_FILEFUNC_VERBOSE}
Exch $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
ClearErrors
GetDllVersion '$0' $1 $2
IfErrors FileFunc_GetFileVersion_error
IntOp $3 $1 >> 16
IntOp $3 $3 & 0x0000FFFF
IntOp $4 $1 & 0x0000FFFF
IntOp $5 $2 >> 16
IntOp $5 $5 & 0x0000FFFF
IntOp $6 $2 & 0x0000FFFF
StrCpy $0 '$3.$4.$5.$6'
goto FileFunc_GetFileVersion_end
FileFunc_GetFileVersion_error:
SetErrors
StrCpy $0 ''
FileFunc_GetFileVersion_end:
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
Exch $0


Line 700: Line 517:
!verbose pop
!verbose pop
!macroend
!macroend
</highlight-nsis>
</highlight-nsis>
<span style="font-size: 110%"><b>Credits:</b></span>
<span style="font-size: 110%"><b>Credits:</b></span>


<em>GetFileAttributes</em> is borrowed from <b>filefunc.nsh</b>. <em>GetSizeOnDisk</em> has been altered slightly and renamed. The original macro is called <em>GetSize</em>. You will find it in the Users Manual under E.1.3.
<em>GetSizeOnDisk</em> has been altered slightly and renamed. The original macro is called <em>GetSize</em>. You will find it in the Users Manual under E.1.3.
[[Category:Code Examples]]
[[Category:Code Examples]]

Revision as of 00:08, 13 February 2013

Author: Bnicer (talk, contrib)


This example code shows you how to get the space used by directories and files.

; A utility for computing the NSIS (or NSIS Unicode) install folder size and the size of
; the uninstaller
; nsissize.nsi
; Compile & run the .exe
 
Name "SOD Tool"
RequestExecutionLevel user
!define LOCAL "" ; Path where local include files reside
OutFile "${LOCAL}nsissize.exe"
!include "${LOCAL}macros.nsh"
ReserveFile "${NSISDIR}\Plugins\Math.dll"
Icon "${LOCAL}arrows.ico"
ShowInstDetails show
 
; Variables
Var NSIS
Var COUNT
Var BLOCK
Var FILES
Var FOLDERS
Var SIZE_B
Var SIZE_M
Var SOD_B
Var SOD_K
Var SOD_M
Var SIZE_UN_B
Var SIZE_UN_K
Var SOD_UN_B
Var SOD_UN_K
 
Function Separator ; comma
  StrCpy $R2 $R1
  StrCpy $COUNT "16" ; 1,000,000,000,000,000 limit
  StrLen $R4 $R1
  loop:
  IntCmp $COUNT 3 endloop endloop 0
  IntCmp $R4 $COUNT 0 +7 0
  IntOp $COUNT $COUNT - 1
  StrCpy $R2 $R2 -$COUNT
  StrCpy $R3 $R1 "" -$COUNT
  StrCpy $R2 "$R2,$R3"
  IntOp $COUNT $COUNT - 2
  Goto loop
  IntOp $COUNT $COUNT - 3
  Goto loop
  endloop:
FunctionEnd
 
Section
; root
  ReadRegStr $NSIS HKLM "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\\
  NSIS Unicode" "InstallLocation"
  IfErrors 0 begin
  ClearErrors
  ReadRegStr $NSIS HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\
  NSIS Unicode" "InstallLocation"
  IfErrors 0 begin
  ClearErrors
  ReadRegStr $NSIS HKLM "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\\
  NSIS ANSI" "InstallLocation"
  IfErrors 0 begin
  ClearErrors
  ReadRegStr $NSIS HKLM "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\\
  NSIS" "InstallLocation"
  IfErrors 0 begin
  ClearErrors
  ReadRegStr $NSIS HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\
  NSIS ANSI" "InstallLocation"
  IfErrors 0 begin
  ClearErrors
  ReadRegStr $NSIS HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\
  NSIS" "InstallLocation"
  IfErrors 0 begin
  ClearErrors
  Goto done
  begin:
  IfFileExists "$NSIS" 0 done
  ${GetClusterSize} $BLOCK
  ${GetSizeOnDisk} "$NSIS" "/S=0B" "" $0 $1 $2
  Math::Script "r3 = ff($0 / 1024 / 1024.0, 16 +2"
  StrCpy $SIZE_B $0
  StrCpy $FILES $1
  StrCpy $FOLDERS $2
  StrCpy $SIZE_M $3
  ${GetSizeOnDisk} "$NSIS" "/S=0B" "$BLOCK" $0 $1 $2
  Math::Script "r4 = ff($0 / 1024.0, 16 +0); r5 = ff(r4 / 1024.0, 16 +2)"
  StrCpy $SOD_B $0
  StrCpy $SOD_K $4
  StrCpy $SOD_M $5
; uninstaller
  IfFileExists "$NSIS\uninst-nsis.exe" 0 done
  ${GetSizeOnDisk} "$NSIS" "/M=uninst-nsis.exe /S=0B" "" $0 $1 $2
  Math::Script "r6 = ff($0 / 1024.0, 16 +1)"
  StrCpy $SIZE_UN_B $0
  StrCpy $SIZE_UN_K $6
  ${GetSizeOnDisk} "$NSIS" "/M=uninst-nsis.exe /S=0B" "$BLOCK" $0 $1 $2
  Math::Script "r7 = ff($0 / 1024.0, 16 +1)"
  StrCpy $SOD_UN_B $0
  StrCpy $SOD_UN_K $7
; format
  StrCpy $R1 $SIZE_B
  Call Separator
  StrCpy $SIZE_B $R2
 
  StrCpy $R1 $SOD_B
  Call Separator
  StrCpy $SOD_B $R2
 
  StrCpy $R1 $SOD_K
  Call Separator
  StrCpy $SOD_K $R2
 
  StrCpy $R1 $SIZE_UN_B
  Call Separator
  StrCpy $SIZE_UN_B $R2
  StrCpy $R1 $SOD_UN_B
  Call Separator
  StrCpy $SOD_UN_B $R2
; output
  DetailPrint ""
  DetailPrint "$NSIS"
  DetailPrint "Size: $SIZE_M MB ($SIZE_B bytes)"
  DetailPrint "SOD: $SOD_M MB ($SOD_B bytes)"
  DetailPrint ""
  DetailPrint "Uninstaller"
  DetailPrint "Size: $SIZE_UN_K KB ($SIZE_UN_B bytes)"
  DetailPrint "SOD: $SOD_UN_K KB ($SOD_UN_B bytes)"
  DetailPrint ""
  DetailPrint "$FILES files $FOLDERS folders $SOD_K Kb"
  DetailPrint ""
  Goto completed
  done:
  DetailPrint "File not found."
  completed:
SectionEnd
 
;--------------------------------
# EOF

You should copy the next code into a separate file: macros.nsh.

; Macros include (TN)
;--------------------------------
/*
 
 FileFunction=[GetSizeOnDisk|GetClusterSize]
 
*/
;_____________________________________________________________________________
;
;                         Macros
;_____________________________________________________________________________
;
; Change log window verbosity (default: 3=no script)
;
; Example:
; !include "sizemacros.nsh"
; !insertmacro GetSizeOnDisk
; ${FILEFUNC_VERBOSE} 4   # all verbosity
; !insertmacro GetClusterSize
; ${FILEFUNC_VERBOSE} 3   # no script
 
!include Util.nsh ; for "CallArtificialFunction"
 
!verbose push
!verbose 3
!ifndef _FILEFUNC_VERBOSE
	!define _FILEFUNC_VERBOSE 3
!endif
!verbose ${_FILEFUNC_VERBOSE}
!define FILEFUNC_VERBOSE `!insertmacro FILEFUNC_VERBOSE`
!verbose pop
 
!macro FILEFUNC_VERBOSE _VERBOSE
	!verbose push
	!verbose 3
	!undef _FILEFUNC_VERBOSE
	!define _FILEFUNC_VERBOSE ${_VERBOSE}
	!verbose pop
!macroend
 
!macro GetSizeOnDiskCall _PATH _OPTIONS _FILESYSTEM _RESULT1 _RESULT2 _RESULT3
	!verbose push
	!verbose ${_FILEFUNC_VERBOSE}
	Push `${_PATH}`
	Push `${_OPTIONS}`
	Push `${_FILESYSTEM}` ; block size
	${CallArtificialFunction} GetSizeOnDisk_
	Pop ${_RESULT1}
	Pop ${_RESULT2}
	Pop ${_RESULT3}
	!verbose pop
!macroend
 
!macro GetClusterSizeCall _RESULT
	!verbose push
	!verbose ${_FILEFUNC_VERBOSE}
	${CallArtificialFunction} GetClusterSize_
	Pop ${_RESULT}
	!verbose pop
!macroend
 
; ---------------
; GetSizeOnDisk (modified "GetSize" - FileFunc.nsh - KiCHiK - Function "FindFiles")
 
!define GetSizeOnDisk `!insertmacro GetSizeOnDiskCall`
!define un.GetSizeOnDisk `!insertmacro GetSizeOnDiskCall`
 
!macro GetSizeOnDisk
!macroend
 
!macro un.GetSizeOnDisk
!macroend
 
; Usage: similar to "GetSize"
 
; For documentation, see the NSIS user manual: E.1.3 GetSize
; Three values are returned
 
; $var1		; Result1: Size/Size on disk
; $var2		; Result2: Sum of files
; $var3		; Result3: Sum of directories
 
; Example: ${GetSizeOnDisk} "$INSTDIR" "/S=0K" "4096" $0 $1 $2
 
; Specifying 4096 (logical size) toggles the result
; Output is size on disk, if used, or size in bytes, if left empty ""
 
!macro GetSizeOnDisk_
	!verbose push
	!verbose ${_FILEFUNC_VERBOSE}
 
	; replace
	Exch $R1
	Exch
	Exch $1
	Exch 2
	; end replace
	Exch $0
	Exch
	Push $2
	Push $3
	Push $4
	Push $5
	Push $6
	Push $7
	Push $8
	Push $9
	; insert code
	Push $R2
	; end insert
	Push $R3
	Push $R4
	Push $R5
	Push $R6
	Push $R7
	Push $R8
	Push $R9
	ClearErrors
 
	StrCpy $R9 $0 1 -1
	StrCmp $R9 '\' 0 +3
	StrCpy $0 $0 -1
	goto -3
	IfFileExists '$0\*.*' 0 FileFunc_GetSize_error
 
	StrCpy $3 ''
	StrCpy $4 ''
	StrCpy $5 ''
	StrCpy $6 ''
	StrCpy $8 0
	StrCpy $R3 ''
	StrCpy $R4 ''
	StrCpy $R5 ''
 
	FileFunc_GetSize_option:
	StrCpy $R9 $1 1
	StrCpy $1 $1 '' 1
	StrCmp $R9 ' ' -2
	StrCmp $R9 '' FileFunc_GetSize_sizeset
	StrCmp $R9 '/' 0 -4
 
	StrCpy $9 -1
	IntOp $9 $9 + 1
	StrCpy $R9 $1 1 $9
	StrCmp $R9 '' +2
	StrCmp $R9 '/' 0 -3
	StrCpy $8 $1 $9
	StrCpy $8 $8 '' 2
	StrCpy $R9 $8 '' -1
	StrCmp $R9 ' ' 0 +3
	StrCpy $8 $8 -1
	goto -3
	StrCpy $R9 $1 2
	StrCpy $1 $1 '' $9
 
	StrCmp $R9 'M=' 0 FileFunc_GetSize_size
	StrCpy $4 $8
	goto FileFunc_GetSize_option
 
	FileFunc_GetSize_size:
	StrCmp $R9 'S=' 0 FileFunc_GetSize_gotosubdir
	StrCpy $6 $8
	goto FileFunc_GetSize_option
 
	FileFunc_GetSize_gotosubdir:
	StrCmp $R9 'G=' 0 FileFunc_GetSize_error
	StrCpy $7 $8
	StrCmp $7 '' +3
	StrCmp $7 '1' +2
	StrCmp $7 '0' 0 FileFunc_GetSize_error
	goto FileFunc_GetSize_option
 
	FileFunc_GetSize_sizeset:
	StrCmp $6 '' FileFunc_GetSize_default
	StrCpy $9 0
	StrCpy $R9 $6 1 $9
	StrCmp $R9 '' +4
	StrCmp $R9 ':' +3
	IntOp $9 $9 + 1
	goto -4
	StrCpy $5 $6 $9
	IntOp $9 $9 + 1
	StrCpy $1 $6 1 -1
	StrCpy $6 $6 -1 $9
	StrCmp $5 '' +2
	IntOp $5 $5 + 0
	StrCmp $6 '' +2
	IntOp $6 $6 + 0
 
	StrCmp $1 'B' 0 +4
	StrCpy $1 1
	StrCpy $2 bytes
	goto FileFunc_GetSize_default
	StrCmp $1 'K' 0 +4
	StrCpy $1 1024
	StrCpy $2 Kb
	goto FileFunc_GetSize_default
	StrCmp $1 'M' 0 +4
	StrCpy $1 1048576
	StrCpy $2 Mb
	goto FileFunc_GetSize_default
	StrCmp $1 'G' 0 FileFunc_GetSize_error
	StrCpy $1 1073741824
	StrCpy $2 Gb
 
	FileFunc_GetSize_default:
	StrCmp $4 '' 0 +2
	StrCpy $4 '*.*'
	StrCmp $7 '' 0 +2
	StrCpy $7 '1'
 
	StrCpy $8 1
	Push $0
	SetDetailsPrint textonly
 
	FileFunc_GetSize_nextdir:
	IntOp $8 $8 - 1
	Pop $R8
	FindFirst $0 $R7 '$R8\$4'
	IfErrors FileFunc_GetSize_show
	StrCmp $R7 '.' 0 FileFunc_GetSize_dir
	FindNext $0 $R7
	StrCmp $R7 '..' 0 FileFunc_GetSize_dir
	FindNext $0 $R7
	IfErrors 0 FileFunc_GetSize_dir
	FindClose $0
	goto FileFunc_GetSize_show
 
	FileFunc_GetSize_dir:
	IfFileExists '$R8\$R7\*.*' 0 FileFunc_GetSize_file
	IntOp $R5 $R5 + 1
	goto FileFunc_GetSize_findnext
 
	FileFunc_GetSize_file:
	StrCpy $R6 0
	StrCmp $5$6 '' 0 +3
	IntOp $R4 $R4 + 1
	goto FileFunc_GetSize_findnext
	FileOpen $9 '$R8\$R7' r
	IfErrors +3
	FileSeek $9 0 END $R6
	FileClose $9
	StrCmp $5 '' +2
	IntCmp $R6 $5 0 FileFunc_GetSize_findnext
	StrCmp $6 '' +2
	IntCmp $R6 $6 0 0 FileFunc_GetSize_findnext
	IntOp $R4 $R4 + 1
	; insert code
	StrCmp $R1 "" FileFunc_GetSize_file_add
	System::Call 'kernel32::GetFileAttributes(t "$R8\$R7")i .R2'
	StrCmp $R2 -1 FileFunc_GetSize_file_logical
	IntOp $R0 $R2 & 0x0800
	IntCmp $R0 0 0 0 +3
	IntOp $R0 $R2 & 0x0200
	IntCmp $R0 0 FileFunc_GetSize_file_logical
	System::Call 'kernel32::GetCompressedFileSize(t "$R8\$R7", i)i .R6'
	IntCmp $R6 4096 FileFunc_GetSize_file_add 0 FileFunc_GetSize_file_add
	StrCpy $R6 4096
	goto FileFunc_GetSize_file_add
	FileFunc_GetSize_file_logical:
	StrCpy $R0 $R1
	IntOp $R6 $R6 + $R0
	IntOp $R1 $R6 % $R0
	StrCmp $R1 0 0 +2
	StrCpy $R1 $R0
	IntOp $R2 $R0 - $R1
	IntOp $R6 $R6 - $R0
	IntOp $R6 $R6 + $R2
	StrCpy $R1 $R0
	FileFunc_GetSize_file_add:
	; end insert
	System::Int64Op $R3 + $R6
	Pop $R3
 
	FileFunc_GetSize_findnext:
	FindNext $0 $R7
	IfErrors 0 FileFunc_GetSize_dir
	FindClose $0
 
	FileFunc_GetSize_show:
	StrCmp $5$6 '' FileFunc_GetSize_nosize
	System::Int64Op $R3 / $1
	Pop $9
	DetailPrint 'Size:$9 $2  Files:$R4  Folders:$R5'
	goto FileFunc_GetSize_subdir
	FileFunc_GetSize_nosize:
	DetailPrint 'Files:$R4  Folders:$R5'
 
	FileFunc_GetSize_subdir:
	StrCmp $7 0 FileFunc_GetSize_preend
	FindFirst $0 $R7 '$R8\*.*'
	StrCmp $R7 '.' 0 FileFunc_GetSize_pushdir
	FindNext $0 $R7
	StrCmp $R7 '..' 0 FileFunc_GetSize_pushdir
	FindNext $0 $R7
	IfErrors 0 FileFunc_GetSize_pushdir
	FindClose $0
	StrCmp $8 0 FileFunc_GetSize_preend FileFunc_GetSize_nextdir
 
	FileFunc_GetSize_pushdir:
	IfFileExists '$R8\$R7\*.*' 0 +3
	Push '$R8\$R7'
	IntOp $8 $8 + 1
	FindNext $0 $R7
	IfErrors 0 FileFunc_GetSize_pushdir
	FindClose $0
	StrCmp $8 0 FileFunc_GetSize_preend FileFunc_GetSize_nextdir
 
	FileFunc_GetSize_preend:
	StrCmp $R3 '' FileFunc_GetSize_nosizeend
	System::Int64Op $R3 / $1
	Pop $R3
	FileFunc_GetSize_nosizeend:
	StrCpy $2 $R4
	StrCpy $1 $R5
	StrCpy $0 $R3
	goto FileFunc_GetSize_end
 
	FileFunc_GetSize_error:
	SetErrors
	StrCpy $0 ''
	StrCpy $1 ''
	StrCpy $2 ''
 
	FileFunc_GetSize_end:
	SetDetailsPrint both
	Pop $R9
	Pop $R8
	Pop $R7
	Pop $R6
	Pop $R5
	Pop $R4
	Pop $R3
	; insert code
	Pop $R2
	; end insert
	Pop $9
	Pop $8
	Pop $7
	Pop $6
	Pop $5
	Pop $4
	Pop $3
	Exch $2
	Exch
	Exch $1
	Exch 2
	Exch $0
 
	!verbose pop
!macroend
 
; ---------------
; GetClusterSize
 
!define GetClusterSize `!insertmacro GetClusterSizeCall`
!define un.GetClusterSize `!insertmacro GetClusterSizeCall`
 
!macro GetClusterSize
!macroend
 
!macro un.GetClusterSize
!macroend
 
!macro GetClusterSize_
	!verbose push
	!verbose ${_FILEFUNC_VERBOSE}
 
	System::Call 'kernel32::GetDiskFreeSpace(i0,*i0r0,*i0r1,*i0r2,*i)'
	IntOp $0 $0 * $1
	Push $0
 
	!verbose pop
!macroend

Credits:

GetSizeOnDisk has been altered slightly and renamed. The original macro is called GetSize. You will find it in the Users Manual under E.1.3.