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" | |||
ShowInstDetails show | ShowInstDetails show | ||
; Variables | ; Variables | ||
Var NSIS | Var NSIS | ||
Var COUNT | Var COUNT | ||
Var BLOCK | Var BLOCK | ||
Line 81: | Line 79: | ||
begin: | begin: | ||
IfFileExists "$NSIS" 0 done | IfFileExists "$NSIS" 0 done | ||
${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 | ||
${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 | Math::Script "r6 = ff($0 / 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 $ | ${GetSizeOnDisk} "$NSIS" "/M=uninst-nsis.exe /S=0B" "$BLOCK" $0 $1 $2 | ||
StrCpy $SOD_UN_K $ | 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 | ||
DetailPrint "" | DetailPrint "" | ||
DetailPrint "$NSIS" | DetailPrint "$NSIS" | ||
DetailPrint "Size: $SIZE_M MB ($SIZE_B bytes)" | DetailPrint "Size: $SIZE_M MB ($SIZE_B bytes)" | ||
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)" | ||
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 | ; Macros include (TN) | ||
;-------------------------------- | ;-------------------------------- | ||
/* | /* | ||
FileFunction=[GetSizeOnDisk|GetClusterSize | FileFunction=[GetSizeOnDisk|GetClusterSize] | ||
*/ | */ | ||
Line 209: | Line 200: | ||
!verbose ${_FILEFUNC_VERBOSE} | !verbose ${_FILEFUNC_VERBOSE} | ||
${CallArtificialFunction} GetClusterSize_ | ${CallArtificialFunction} GetClusterSize_ | ||
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 "" + | 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 | 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>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.