Wie kann ich installieren freien Speicherplatz während einer Nullsoft schweigt überprüfen?
Frage
Im Silent-Modus installieren wird der Benutzer nicht über das Installationsziel mit dem PageEx directory
, und deshalb werden die Funktionen DirVerify
und GetInstDirError
werden nie genannt.
Dies gilt auch für Installationen, die das Installationsziel (eine schlechte Idee) aus dem gleichen Grunde wie oben hart codieren. Die PageEx directory
werden nie aufgerufen
Lösung
Ihr Beispielcode ist in Ordnung, aber der Aufruf von $ {} DriveSpace- auf Win9x scheitern könnte. Ich entfernte auch die Notwendigkeit, den Abschnitt-IDs angeben
!define APPNAME "CalcEnoughSpace"
name "${APPNAME}"
outfile "$%temp%\${APPNAME}.exe"
ShowInstDetails show
RequestExecutionLevel user
installdir "$Temp"
AllowRootDirInstall true
!include Sections.nsh
!include LogicLib.nsh
Function .onInit
push $instdir
call VerifyFreeSpace
pop $0
${If} $0 < 1
MessageBox mb_iconstop "Not enough free space!"
${EndIf}
FunctionEnd
page instfiles
Section !a
AddSize 10000
SectionEnd
Section /o b
AddSize 10000
SectionEnd
SectionGroup grp
Section c
AddSize 10000
SectionEnd
SectionGroupEnd
Function VerifyFreeSpace
System::Store s
pop $0 ;path to check
Push 0 ;default to no
System::Call 'kernel32::GetDiskFreeSpaceEx(tr0,*l.r1,*l,*l)i.r2'
${If} $2 < 1
StrCpy $0 $0 3
System::Call 'kernel32::GetDiskFreeSpace(tr0,*i.r1,*i.r2,*i.r3,*i)i.r4'
IntCmpU $4 0 ret
IntOp $1 $1 * $2
System::Int64Op $1 * $3
pop $1
${EndIf}
System::Int64Op $1 / 1024 ;to kb
pop $1
StrCpy $4 0 ;size
StrCpy $2 0 ;section idx
loop:
ClearErrors
SectionGetFlags $2 $3
IfErrors testspace
IntOp $3 $3 & ${SF_SELECTED}
${If} $3 <> 0
SectionGetSize $2 $3
IntOp $4 $4 + $3
${EndIf}
IntOp $2 $2 + 1
goto loop
testspace:
pop $2 ;throw away default return value
System::Int64Op $1 > $4
ret:
System::Store l
FunctionEnd
ich nur begrenzt getestet haben, hoffentlich gibt es keine Fehler:)
Andere Tipps
Ich schrieb eine Funktion CheckFreeSpace
in NSIS genannt, dies zu tun. Leider hat es die folgenden Einschränkungen:
- Um die Größe aller Abschnitte in Ihrer Installation zu berechnen, müssen Sie
CheckFreeSpace
ändern jeden Abschnitt hinzuzufügen, indem jede Variable zu wissen, dass jeder Abschnitt id in geschrieben wurde. Ich kann nicht einen Weg Iteration über alle Abschnitte finden, die mit NSIS installiert werden. - Installation Laufwerk muss berechnet werden, da
${DriveSpace}
einen Laufwerksbuchstaben erfordert, kein Pfad in ein beliebiges Verzeichnis. Der Laufwerksbuchstaben String wird mitStrCpy $instdrive $INSTDIR 3
berechnet. Wenn die$INSTDIR
Variable ein relativer Pfad ist oder nicht mit einem String wieC:\
beginnt, wird dies nicht kann. - Wenn die Installation nicht fortgesetzt werden kann, erzeugt es eine
MessageBox
. Sie können dieMessageBox
unterdrücken, indem/SD IDOK
am Ende der Anweisung hinzufügen, aber dann wird der Benutzer nicht von den Installationsfehlern informiert: Ich kann nicht einen Weg finden, zu emittieren von NSISstdout
. Vielleicht ist der Return-Code von dem Installateur ist genug? - Wenn die freie Speicherplatz wirklich gering ist (wie 10kb), wird der Installer nicht ausgeführt; es keinen Platz hat seine temporären DLL in das
\tmp
Verzeichnis zu entpacken.
Auch in meiner Implementierung unten, hat CheckFreeSpace
einen fest codierten Wert für den Raum frei nach der Installation. Offensichtlich, dass parametrierbar.
Hier ist es innerhalb einer Probe Installateur:
!include FileFunc.nsh
!insertmacro DriveSpace
Name "CheckFreeSpace"
OutFile "C:\CheckFreeSpace.exe"
InstallDir C:\tmp\checkfreespace
Page instfiles
Section "install_section" install_section_id
Call CheckFreeSpace
CreateDirectory $INSTDIR
SetOutPath $INSTDIR
File "C:\installme.bat"
WriteUninstaller "$INSTDIR\Uninstall.exe"
DetailPrint "Installation Successful."
SectionEnd
Section "Uninstall"
RMDIR /r "$INSTDIR"
SectionEnd
Function CheckFreeSpace
var /GLOBAL installsize
var /GLOBAL adjustedinstallsize
var /GLOBAL freespace
var /GLOBAL instdrive
; Verify that we have sufficient space for the install
; SectionGetSize returns the size of each section in kilobyte.
SectionGetSize ${install_section_id} $installsize
; Adjust the required install size by 10mb, as a minimum amount
; of free space left after installation.
IntOp $adjustedinstallsize $installsize + 10240
; Compute the drive that is the installation target; the
; ${DriveSpace} macro will not accept a path, it must be a drive.
StrCpy $instdrive $INSTDIR 3
; Compute drive space free in kilobyte
${DriveSpace} $instdrive "/D=F /S=K" $freespace
DetailPrint "Determined installer needs $adjustedinstallsize kb ($installsize kb) while $freespace kb is free"
IntCmp $adjustedinstallsize $freespace spaceok spaceok
MessageBox MB_OK|MB_ICONSTOP "Insufficient space for installation. Please free space for installation directory $INSTDIR and try again."
DetailPrint "Insufficient space for installation. Installer needs $adjustedinstallsize kb, but freespace is only $freespace kb."
Abort "Insufficient space for installation."
spaceok:
DetailPrint "Installation target space is sufficient"
FunctionEnd
Haben Sie einen Beispielskript haben für unbeaufsichtigte Installation?