Get size on disk: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
(Size On Disk (SOD) utility) |
m (Size On Disk (SOD) utility) |
||
Line 158: | Line 158: | ||
; | ; | ||
; Example: | ; Example: | ||
; !include " | ; !include "macros.nsh" | ||
; !insertmacro GetSizeOnDisk | ; !insertmacro GetSizeOnDisk | ||
; ${FILEFUNC_VERBOSE} 4 # all verbosity | ; ${FILEFUNC_VERBOSE} 4 # all verbosity |
Revision as of 11:54, 14 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 "macros.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 ; insert code StrCmp $R1 "" FileFunc_GetSize_fileopen StrCpy $R0 0 System::Call 'kernel32::GetFileAttributes(t "$R8\$R7")i .R2' StrCmp $R2 -1 FileFunc_GetSize_fileopen IntOp $R0 $R2 & 0x0800 IntCmp $R0 0 0 0 +3 IntOp $R0 $R2 & 0x0200 IntCmp $R0 0 FileFunc_GetSize_fileopen System::Call 'kernel32::GetCompressedFileSize(t "$R8\$R7", i)i .R6' IntCmp $R6 4096 +2 0 +2 StrCpy $R6 4096 goto FileFunc_GetSize_fileclose FileFunc_GetSize_fileopen: ; end insert FileOpen $9 '$R8\$R7' r IfErrors +3 FileSeek $9 0 END $R6 FileClose $9 ; insert code FileFunc_GetSize_fileclose: ; end insert 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 StrCmp $R0 0 0 FileFunc_GetSize_file_add 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.