代码之家  ›  专栏  ›  技术社区  ›  Jared Oberhaus

在NullSoft静默安装期间,如何检查可用空间?

  •  2
  • Jared Oberhaus  · 技术社区  · 16 年前

    在静默安装模式下,不会向用户询问 PageEx directory ,因此功能 DirVerify GetInstDirError 从未打过电话。

    这也适用于以与上述相同的原因对安装目标进行硬编码的安装: pageex目录 从不调用。

    3 回复  |  直到 15 年前
        1
  •  2
  •   Anders    16 年前

    您的示例代码正常,但在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
    

    我只做了有限的测试,希望没有错误:)

        2
  •  1
  •   Jared Oberhaus    16 年前

    我写了一个函数 CheckFreeSpace 在NSI做这个。不幸的是,它有以下限制:

    • 要计算安装中所有部分的大小,必须修改 检查自由空间 通过知道每个节ID被写入的每个变量来添加每个节。我找不到一种方法来遍历将使用NSI安装的所有部分。
    • 必须计算安装驱动器,因为 ${DriveSpace} 需要驱动器号,而不是任意目录的路径。驱动器号字符串是用 StrCpy $instdrive $INSTDIR 3 . 如果 $INSTDIR 变量是相对路径或不是以字符串开头,例如 C:\ ,这将失败。
    • 如果安装无法继续,它将生成 MessageBox . 您可以抑制 对话框 通过添加 /SD IDOK 在语句的末尾,但是用户没有收到安装失败的通知:我找不到一种方法来发出 stdout 来自NSIS。也许安装程序返回的代码就足够了?
    • 如果磁盘可用空间真的很低(如10KB),安装程序将根本无法运行;它没有空间将其临时dll解包到 \tmp 目录。

    另外,在下面的实现中, 检查自由空间 有一个硬编码值,用于安装后释放空间。显然,这可以参数化。

    这里是一个示例安装程序:

    !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
    
        3
  •  0
  •   Tiberiu    15 年前

    您有无提示安装的示例脚本吗?