windows - Hvordan kan jeg kontrollere ledig plads under en NullSoft stille installation?

Indlæg af Hanne Mølgaard Plasc

Problem



I stille installationstilstand bliver brugeren ikke bedt om installationsmål med PageEx directory, og derfor bliver funktionerne DirVerify og GetInstDirError aldrig kaldt. [19] [20] [21]


Dette gælder også for installationer, som hardcode installationsmål (en dårlig ide) af samme grund som ovenfor: PageEx directory påberåbes aldrig.

Bedste reference


Din prøvekode er ok, men at kalde $ {DriveSpace} på Win9x kunne mislykkes. Jeg fjernede også behovet for at angive sektionens id'er


!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


Jeg har kun begrænset test, forhåbentlig er der ingen fejl :)

Andre referencer 1


Jeg skrev en funktion kaldet CheckFreeSpace i NSIS for at gøre dette. Desværre har den følgende begrænsninger:



  • For at beregne størrelsen af ​​alle sektioner i din installation skal du ændre CheckFreeSpace for at tilføje hver sektion ved at kende hver variabel, at hver sektion id blev skrevet ind. Jeg kan ikke finde en måde at gentage over alle sektioner, der vil blive installeret ved hjælp af NSIS.

  • Installationsdrevet skal beregnes, fordi ${DriveSpace} kræver et drevbogstav, ikke en vej til en vilkårlig mappe. Drevbogstavet beregnes med StrCpy $instdrive $INSTDIR 3. Hvis variablen $INSTDIR er en relativ sti eller begynder ikke med en streng som C:, vil dette mislykkes.

  • Hvis installationen ikke kan fortsætte, produceres en MessageBox. Du kan undertrykke MessageBox ved at tilføje /SD IDOK i slutningen af ​​sætningen, men så er brugeren ikke informeret om installationsfejlen: Jeg kan ikke finde en måde at udstede til stdout fra NSIS. Måske er returkode fra installationsprogrammet nok?

  • Hvis diskpladsen er meget lav (ligesom 10kb), vil installationsprogrammet slet ikke løbe, det har ikke plads til at udpakke sine midlertidige DLL'er i mappen mp.



Også i min implementering nedenfor har CheckFreeSpace en hardcoded værdi for pladsen fri efter installationen. Det kan naturligvis parameteriseres.


Her er det inden for et prøveinstallationsprogram:


!include FileFunc.nsh
!insertmacro DriveSpace

Name "CheckFreeSpace"
OutFile "C:CheckFreeSpace.exe"

InstallDir C:	mpcheckfreespace

Page instfiles

Section "install\_section" install\_section\_id
    Call CheckFreeSpace

    CreateDirectory $INSTDIR
    SetOutPath $INSTDIR
    File "C:installme.bat"

    WriteUninstaller "$INSTDIRUninstall.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

Andre referencer 2


Har du et eksempel script til lydløs installation?