2009-06-12 5 views
1

En mode d'installation silencieuse, l'utilisateur n'est pas interrogé sur la cible d'installation avec le PageEx directory et, par conséquent, les fonctions DirVerify et GetInstDirError ne sont jamais appelées.Comment puis-je vérifier l'espace disponible lors d'une installation silencieuse de NullSoft?

Cela s'applique également aux installations qui codent en dur la cible d'installation (une mauvaise idée) pour la même raison que ci-dessus: le PageEx directory n'est jamais appelé.

Répondre

1

Votre exemple de code est ok, mais appelant $ {} DriveSpace sur Win9x pourrait échouer. J'ai aussi enlevé la nécessité de préciser le

!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 

de id section Je n'ai des essais limités, nous l'espérons, il n'y a aucun bug :)

+0

Merci @Anders, je vais essayer cela. Je n'écris jamais rien pour Win95, mais mieux vaut être préparé ... –

1

J'ai écrit une fonction appelée CheckFreeSpace dans NSIS pour ce faire. Malheureusement, il a les limitations suivantes:

  • Pour calculer la taille de toutes les sections de votre installation, vous devez modifier CheckFreeSpace pour ajouter chaque section, en connaissant chaque variable qui a été écrit chaque identifiant de section dans. Je ne peux pas trouver un moyen d'itérer sur toutes les sections qui seront installées en utilisant NSIS.
  • Le lecteur d'installation doit être calculé car ${DriveSpace} requiert une lettre de lecteur, pas un chemin d'accès à un répertoire arbitraire. La chaîne de lettre de lecteur est calculée avec StrCpy $instdrive $INSTDIR 3. Si la variable $INSTDIR est un chemin relatif ou ne commence pas par une chaîne telle que C:\, cela échouera. Si l'installation ne peut pas continuer, elle produit un MessageBox. Vous pouvez supprimer le MessageBox en ajoutant /SD IDOK à la fin de l'instruction, mais l'utilisateur n'est pas informé de l'échec de l'installation: je ne trouve pas de moyen d'émettre à stdout à partir de NSIS. Peut-être que le code de retour de l'installateur est suffisant?
  • Si l'espace libre du disque est vraiment faible (comme 10kb), le programme d'installation ne fonctionnera pas du tout; il n'a pas d'espace pour décompresser ses DLL temporaires dans le répertoire \tmp.

En outre, dans ma mise en œuvre ci-dessous, CheckFreeSpace a une valeur codée en dur pour l'espace libre après l'installation. Évidemment, cela peut être paramétré.

Ici, il est dans un installateur exemple:

!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 
+0

Si les hypothèses de ma question ou de ma réponse sont fausses, veuillez les corriger. À ce moment, ce code semble fonctionner avec de faibles conditions d'espace libre. –

+0

la section id est juste un nombre à partir de 0, donc vous pouvez juste faire une boucle pour vérifier toutes les sections, appel SectionGetFlags pour voir si la section est sélectionnée/vérifiée, si appelez SectionGetSize, si le drapeau d'erreur est défini après Si vous appelez SectionGetFlags, vous avez atteint la fin. – Anders

+0

En ce qui concerne la sortie vers stdout, NSIS est une application GUI, donc il n'y a pas vraiment de manipulation de console. Sur XP et plus tard, c'est possible si vous utilisez le plugin système, voir http://forums.winamp.com/showthread.php?postid=2303779#post2303779 – Anders

0

Avez-vous un exemple de script pour une installation silencieuse?

Questions connexes