User:Bnicer: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
No edit summary
(NSIS and I)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<span style="font-size: 130%"><b>Get Size On Disk</b></span>
My current NSIS-related activities include testing, testing and more testing ...
 
This example code shows you how to get the space used by directories and files.
<highlight-nsis>
<highlight-nsis>
; A utility for computing the NSIS (or NSIS Unicode) install folder size and the size of
ExecWait '"$UNINSTSTR" /U _?=$UNINST\bin'
; 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
</highlight-nsis>
</highlight-nsis>
You should copy the next code into a separate file: <b>macros.nsh</b>.
<highlight-nsis>
; 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
</highlight-nsis>
<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.

Latest revision as of 01:14, 16 March 2013

My current NSIS-related activities include testing, testing and more testing ...

ExecWait '"$UNINSTSTR" /U _?=$UNINST\bin'