由于使用了 SetOverwrite,NSIS 部分大小增加了一倍

tom*_*gic 5 nsis

我继承了一个安装程序脚本,我对它声称需要两倍于实际需要的空间感到恼火。

我发现这是由于每个部分的使用方式SetOverwrite(因为它们被重新用于修复安装?)。我知道有必要File在每个 If/Else 块中保留重复的命令,因为它是如何SetOverwrite工作的(见下文),但我已经确认这会导致自动节大小计算加倍。

${MementoSection} $(APP_Section_SecHelp) SecHelp
  SetDetailsPrint textonly
  DetailPrint  $(APP_DetailPrint_SecHelp)
  SetDetailsPrint listonly

  SetOutPath $INSTDIR
  SectionIn 1 2
    ${If} $SetOverwriteOn == TRUE
      SetOverwrite ifnewer
      File /r "${APP_SOURCE_DIR}\Help"
    ${Else}
      SetOverwrite off
      File /r "${APP_SOURCE_DIR}\Help"
    ${EndIf}
  SectionGetFlags ${SecHelp} $SecHelp_GetFlag
${MementoSectionEnd}
Run Code Online (Sandbox Code Playgroud)

这是我应该改变的糟糕设计模式吗?我是否需要添加一个 hack 来调用SectionGetSize,除以 2 并调用SectionSetSize?

And*_*ers 2

就我个人而言,我只会同时使用SetOverwrite ifnewer两者,但如果您绝对想按照自己的方式进行操作,那么使用SectionSetSize是一种选择。

您可以做的另一件事是将修复File /r指令放入您从该部分调用的单独函数中。该函数的缺点是进度条在提取过程中不会移动太多。

第三种替代方法是将某些修复任务放在默认情况下未选中的单独部分中,并在处于修复模式时启用它。

编辑:这是一个使用SectionSetSize的示例:

!include LogicLib.nsh
InstallDir $Temp
Page Components InitComponentsPage
Page Directory
Page InstFiles  

!macro ModifySectionHack SID TEMPVAR
SectionGetSize ${SID} ${TEMPVAR}
IntOp ${TEMPVAR} ${TEMPVAR} / 2
SectionSetSize ${SID} ${TEMPVAR}
!macroend

Function InitComponentsPage
StrCpy $0 0
loop:
    ClearErrors
    SectionGetFlags $0 $1 ; The error flag is set if we try to access a section that does not exist
    IfErrors done
    !insertmacro ModifySectionHack $0 $1
    IntOp $0 $0 + 1
    Goto loop
done:
FunctionEnd

Section "Foo"
InitPluginsDir ; Need a place to extract to for this example
SetOutPath $PluginsDir

${If} 1 <> 2 ; Don't really care about the result
    SetOverwrite ifnewer
    File "${NSISDIR}\bin\makensis.exe" ; ~400kb
${Else}
    SetOverwrite off
    File "${NSISDIR}\bin\makensis.exe"
${EndIf}
SectionEnd

Section "Bar"
InitPluginsDir ; Need a place to extract to for this example
SetOutPath $PluginsDir

${If} 1 <> 2 ; Don't really care about the result
    SetOverwrite ifnewer
    File "${NSISDIR}\nsis.exe" ; ~700kb
${Else}
    SetOverwrite off
    File "${NSISDIR}\nsis.exe"
${EndIf}
SectionEnd
Run Code Online (Sandbox Code Playgroud)

这会循环遍历所有部分并调整所有部分,但我不确定这是否是一个好主意。如果这是我的脚本,那么我将在存在 SetOverwrite 问题的每个部分上手动调用 ModifySectionHack:

!include LogicLib.nsh
InstallDir $Temp
Page Components
Page Directory
Page InstFiles

!macro ModifySectionHack SID TEMPVAR
SectionGetSize ${SID} ${TEMPVAR}
IntOp ${TEMPVAR} ${TEMPVAR} / 2
SectionSetSize ${SID} ${TEMPVAR}
!macroend

Section "Foo" SID_FOO
InitPluginsDir ; Need a place to extract to for this example
SetOutPath $PluginsDir

${If} 1 <> 2 ; Don't really care about the result
    SetOverwrite ifnewer
    File "${NSISDIR}\bin\makensis.exe" ; ~400kb
${Else}
    SetOverwrite off
    File "${NSISDIR}\bin\makensis.exe"
${EndIf}
SectionEnd

Section "Bar"
${If} 1 = 2
  File /r "${NSISDIR}\stubs"
${EndIf}
SectionEnd

Section "Baz" SID_BAZ
InitPluginsDir ; Need a place to extract to for this example
SetOutPath $PluginsDir

${If} 1 <> 2 ; Don't really care about the result
    SetOverwrite ifnewer
    File "${NSISDIR}\nsis.exe" ; ~700kb
${Else}
    SetOverwrite off
    File "${NSISDIR}\nsis.exe"
${EndIf}
SectionEnd

Function .onInit
; Adjust the section size for the sections that use SetOverwrite:
!insertmacro ModifySectionHack ${SID_FOO} $1
!insertmacro ModifySectionHack ${SID_BAZ} $1
FunctionEnd
Run Code Online (Sandbox Code Playgroud)