サイレント インストール モードでは、ユーザーは を使用してインストール ターゲットについて尋ねられないPageEx directory
ため、関数DirVerify
およびGetInstDirError
が呼び出されることはありません。
これは、上記と同じ理由で、インストール ターゲットをハードコードするインストールにも適用できます (悪い考えです):PageEx directory
は呼び出されません。
サイレント インストール モードでは、ユーザーは を使用してインストール ターゲットについて尋ねられないPageEx directory
ため、関数DirVerify
およびGetInstDirError
が呼び出されることはありません。
これは、上記と同じ理由で、インストール ターゲットをハードコードするインストールにも適用できます (悪い考えです):PageEx directory
は呼び出されません。
サンプル コードは問題ありませんが、Win9x で ${DriveSpace} を呼び出すと失敗する可能性があります。また、セクション ID を指定する必要がなくなりました
!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
私は限られたテストしか行いませんでした。バグがないことを願っています:)
CheckFreeSpace
これを行うために、NSIS で呼び出される関数を作成しました。残念ながら、次の制限があります。
CheckFreeSpace
各セクション ID が書き込まれた各変数を把握して、各セクションを追加するように変更する必要があります。NSIS を使用してインストールされるすべてのセクションを反復処理する方法が見つかりません。${DriveSpace}
任意のディレクトリへのパスではなく、ドライブ文字が必要なため、インストール ドライブを計算する必要があります。ドライブ文字列は で計算されStrCpy $instdrive $INSTDIR 3
ます。$INSTDIR
変数が相対パスであるか、または などの文字列で始まらない場合C:\
、これは失敗します。MessageBox
. MessageBox
ステートメントの最後に追加することで抑制できますが/SD IDOK
、ユーザーにはインストールの失敗が通知されません: I can't find a way to emit to stdout
from NSIS. おそらく、インストーラーからのリターン コードで十分でしょうか?\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
サイレント インストール用のサンプル スクリプトはありますか?