【问题标题】:How can I check free space during a NullSoft silent install?如何在 NullSoft 静默安装期间检查可用空间?
【发布时间】:2009-06-12 21:35:49
【问题描述】:

在静默安装模式下,不会使用PageEx directory 询问用户安装目标,因此永远不会调用函数DirVerifyGetInstDirError

这也适用于对安装目标进行硬编码的安装(一个坏主意),原因与上述相同:永远不会调用 PageEx directory

【问题讨论】:

    标签: windows installation nsis diskspace


    【解决方案1】:

    您的示例代码没问题,但在 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
    

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

    【讨论】:

    • 谢谢@Anders,我会试试这个。我从来没有为Win95写过任何东西,但最好做好准备......
    【解决方案2】:

    我在 NSIS 中编写了一个名为 CheckFreeSpace 的函数来执行此操作。不幸的是,它有以下限制:

    • 要计算安装中所有部分的大小,您必须修改 CheckFreeSpace 以添加每个部分,方法是知道每个部分 id 写入的每个变量。我找不到遍历将使用 NSIS 安装的所有部分的方法。
    • 必须计算安装驱动器,因为${DriveSpace} 需要驱动器号,而不是任意目录的路径。驱动器号字符串使用StrCpy $instdrive $INSTDIR 3 计算。如果$INSTDIR 变量是相对路径或不以C:\ 等字符串开头,则会失败。
    • 如果安装无法继续,则会生成MessageBox。您可以通过在语句末尾添加/SD IDOK 来抑制MessageBox,但随后不会通知用户安装失败:我找不到从NSIS 发送到stdout 的方法。也许安装程序的返回码就足够了?
    • 如果磁盘可用空间非常低(如 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
    

    【讨论】:

    • 如果我的问题或答案中的假设有误,请更正。目前,此代码似乎适用于可用空间不足的情况。
    • section id只是一个从0开始的数字,所以你可以循环检查所有section,调用SectionGetFlags查看是否选中/选中了section,如果是,调用SectionGetSize,如果在调用 SectionGetFlags 后设置了错误标志,那么你已经到了终点
    • 就输出到标准输出而言,NSIS 是一个 GUI 应用程序,因此实际上没有任何控制台处理。在 XP 及更高版本上,如果您使用系统插件,请参阅 forums.winamp.com/showthread.php?postid=2303779#post2303779
    【解决方案3】:

    您有静默安装的示例脚本吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 2020-06-03
      • 2021-01-01
      • 1970-01-01
      相关资源
      最近更新 更多