Я написал функцию под названием CheckFreeSpace
в NSIS для этого. К сожалению, он имеет следующие ограничения:
- Чтобы вычислить размер всех разделов в вашей установке, вы должны изменить
CheckFreeSpace
, чтобы добавить каждый раздел, зная каждую переменную, в которую записан каждый идентификатор раздела. Я не могу найти способ перебора всех разделов, которые будут установлены с использованием NSIS.
- Установочный диск должен быть вычислен, поскольку
${DriveSpace}
требует буквы диска, а не пути к произвольному каталогу. Буквенная строка диска вычисляется с StrCpy $instdrive $INSTDIR 3
. Если переменная $INSTDIR
является относительным путем или не начинается со строки, такой как C:\
, произойдет сбой.
- Если установка не может быть продолжена, выдается
MessageBox
. Вы можете подавить MessageBox
, добавив /SD IDOK
в конце оператора, но тогда пользователь не будет проинформирован о сбое установки: я не могу найти способ отправки в stdout
из NSIS. Возможно, достаточно кода возврата из установщика?
- Если свободного места на диске очень мало (например, 10 КБ), программа установки не будет работать вообще; в нем нет места для распаковки временных библиотек 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