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 1: | Line 1: | ||
{{PageAuthor|Bnicer}} | |||
This example code shows you how to get the space used by directories and files. | This example code shows you how to get the space used by directories and files. | ||
<highlight-nsis> | <highlight-nsis> |
Revision as of 10:25, 12 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 ZIP Var ZIP_UN 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 ${GetFileAttributes} "$NSIS" "COMPRESSED" $ZIP ${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 ${GetFileAttributes} "$NSIS\uninst-nsis.exe" "COMPRESSED" $ZIP_UN ${GetSizeOnDisk} "$NSIS" "/M=uninst-nsis.exe /S=0B" "" $0 $1 $2 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_K $6 StrCpy $SOD_UN_B $7 StrCpy $SOD_UN_K $8 ; 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 ; note: with compression SOD lines are incorrect DetailPrint "" DetailPrint "$NSIS" 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 "" DetailPrint "Uninstaller" 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 "" 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 file ;-------------------------------- /* FileFunction=[GetSizeOnDisk|GetClusterSize|GetFileAttributes] */ ;_____________________________________________________________________________ ; ; 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 !macro GetFileAttributesCall _PATH _ATTR _RESULT !verbose push !verbose ${_FILEFUNC_VERBOSE} Push `${_PATH}` Push `${_ATTR}` ${CallArtificialFunction} GetFileAttributes_ 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 "" +10 0 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 ; 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 ; --------------- ; 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 !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:
GetFileAttributes is borrowed from filefunc.nsh. 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.