User:Bnicer: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
No edit summary |
No edit summary |
||
| Line 708: | Line 708: | ||
<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>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> | |||
Revision as of 06:51, 8 February 2013
Get Size On Disk
There are two types of sizes. The physical size of files in bytes vs. the logical size on disk used. This NSIS example code shows you how to get both sizes all in one go.
; A utility for computing the NSIS (or NSIS Unicode) 32-bit install folder size and the ; size of the uninstaller ; nsissize.nsi ; Compile & run the .exe ; Note: where either the folder or the uninstaller have been compressed, size on disk ; results will not be shown, as they would be incorrect 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 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 called 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 (4KB clusters), if used, or size in bytes, if left empty "" ; Caution: All writable variables go on the stack; make sure you save them before !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.