Как мога да проверя свободното място по време на тиха инсталация на NullSoft?

В режим на тихо инсталиране потребителят не се пита за целта за инсталиране с PageEx directory и следователно функциите DirVerify и GetInstDirError никога не се извикват.

Това е приложимо и за инсталации, които твърдо кодират инсталационната цел (лоша идея) поради същата причина като по-горе: PageEx directory никога не се извиква.


person Jared Oberhaus    schedule 12.06.2009    source източник


Отговори (3)


Вашият примерен код е ок, но извикването на ${DriveSpace} на Win9x може да се провали. Премахнах и необходимостта да се посочват идентификаторите на секциите

!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

Направих само ограничено тестване, надявам се да няма грешки :)

person Anders    schedule 13.06.2009
comment
Благодаря @Anders, ще опитам това. Никога не пиша нищо за Win95, но по-добре да съм подготвен... - person Jared Oberhaus; 20.06.2009

Написах функция, наречена CheckFreeSpace в NSIS, за да направя това. За съжаление има следните ограничения:

  • За да изчислите размера на всички секции във вашата инсталация, трябва да модифицирате CheckFreeSpace, за да добавите всяка секция, като знаете всяка променлива, в която е записан идентификаторът на всяка секция. Не мога да намеря начин за повторение на всички секции, които ще бъдат инсталирани с помощта на NSIS.
  • Инсталационното устройство трябва да бъде изчислено, защото ${DriveSpace} изисква буква на устройство, а не път към произволна директория. Низът с букви на устройството се изчислява с StrCpy $instdrive $INSTDIR 3. Ако променливата $INSTDIR е относителен път или не започва с низ като C:\, това няма да успее.
  • Ако инсталацията не може да продължи, се извежда MessageBox. Можете да потиснете MessageBox, като добавите /SD IDOK в края на израза, но тогава потребителят не е информиран за неуспешната инсталация: Не мога да намеря начин да излъчвам към stdout от NSIS. Може би кодът за връщане от инсталатора е достатъчен?
  • Ако свободното пространство на диска е наистина малко (например 10kb), инсталаторът изобщо няма да стартира; той няма място за разопаковане на своите временни DLL файлове в директорията \tmp.

Също така, в моята реализация по-долу, CheckFreeSpace има твърдо кодирана стойност за свободното пространство след инсталирането. Очевидно това може да бъде параметризирано.

Ето го в примерен инсталатор:

!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
person Jared Oberhaus    schedule 12.06.2009
comment
Ако предположенията в моя въпрос или отговор са грешни, моля, коригирайте ги. Понастоящем този код изглежда работи при условия на малко свободно пространство. - person Jared Oberhaus; 13.06.2009
comment
идентификаторът на секцията е просто число, започващо от 0, така че можете просто да направите цикъл, за да проверите всички секции, да извикате SectionGetFlags, за да видите дали секцията е избрана/проверена, ако е, извикайте SectionGetSize, ако флагът за грешка е зададен след извикване SectionGetFlags, стигнахте до края - person Anders; 13.06.2009
comment
Що се отнася до изхода към stdout, NSIS е GUI приложение, така че всъщност няма никаква конзолна обработка. На XP и по-нови е възможно, ако използвате системния плъгин, вижте forums.winamp. com/showthread.php?postid=2303779#post2303779 - person Anders; 13.06.2009

Имате ли примерен скрипт за тиха инсталация?

person Community    schedule 07.08.2009