由于使用SETOVERRIDE,NSIS部分大小翻了一番

由于使用SETOVERRIDE,NSIS部分大小翻了一番,nsis,Nsis,我继承了一个安装程序脚本,我对它声称需要两倍于实际需要的空间感到恼火 我发现这是由于每个部分如何使用SetOverwrite(因为它们用于修复安装?)。我知道,由于SetOverwrite的工作原理(见下文),有必要在每个If/Else块中保留重复的文件命令,但我已确认这会导致自动截面尺寸计算加倍 ${MementoSection} $(APP_Section_SecHelp) SecHelp SetDetailsPrint textonly DetailPrint $(APP_Det

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

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

${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}

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

我个人只想使用
SetOverwrite ifnewer
,但如果你绝对想这样做,那么使用
SectionSetSize
是一个选项

您可以做的另一件事是将repair
File/r
指令放在一个单独的函数中,您可以从该部分调用该函数。函数的缺点是progressbar在提取期间不会移动太多

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

编辑:下面是一个使用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
!包括LogicLib.nsh
InstallDir$Temp
页面组件初始化组件页面
页面目录
页面文件
!宏ModifySectionHack SID TEMPVAR
SectionGetSize${SID}${TEMPVAR}
IntOp${TEMPVAR}${TEMPVAR}/2
SectionSetSize${SID}${TEMPVAR}
!宏端
函数InitComponentsPage
StrCpy$0
循环:
明显错误
SectionGetFlags$0$1;如果尝试访问不存在的节,则会设置错误标志
错误完成了
!insertmacro ModifySectionHack$0$1
输入$0$0+1
转到环路
完成:
功能端
“Foo”一节
InitPluginsDir;对于本例,需要提取到的位置
SetOutPath$PluginsDir
${If}12;我真的不在乎结果
设置更新的
文件“${NSISDIR}\bin\makensis.exe”~400kb
${Else}
抵销
文件“${NSISDIR}\bin\makensis.exe”
${EndIf}
分段结束
“酒吧”一节
InitPluginsDir;对于本例,需要提取到的位置
SetOutPath$PluginsDir
${If}12;我真的不在乎结果
设置更新的
文件“${NSISDIR}\nsis.exe”~700kb
${Else}
抵销
文件“${NSISDIR}\nsis.exe”
${EndIf}
分段结束
这将在所有部分中循环并调整所有部分,但我不确定这是否是一个好主意。如果这是我的脚本,那么我会在每个有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
!包括LogicLib.nsh
InstallDir$Temp
页面组件
页面目录
页面文件
!宏ModifySectionHack SID TEMPVAR
SectionGetSize${SID}${TEMPVAR}
IntOp${TEMPVAR}${TEMPVAR}/2
SectionSetSize${SID}${TEMPVAR}
!宏端
“Foo”部分SID_Foo
InitPluginsDir;对于本例,需要提取到的位置
SetOutPath$PluginsDir
${If}12;我真的不在乎结果
设置更新的
文件“${NSISDIR}\bin\makensis.exe”~400kb
${Else}
抵销
文件“${NSISDIR}\bin\makensis.exe”
${EndIf}
分段结束
“酒吧”一节
${If}1=2
文件/r“${NSISDIR}\stubs”
${EndIf}
分段结束
“Baz”部分SID_Baz
InitPluginsDir;对于本例,需要提取到的位置
SetOutPath$PluginsDir
${If}12;我真的不在乎结果
设置更新的
文件“${NSISDIR}\nsis.exe”~700kb
${Else}
抵销
文件“${NSISDIR}\nsis.exe”
${EndIf}
分段结束
函数。onInit
; 调整使用SetOverwrite的节的节大小:
!insertmacro ModifySectionHack${SID_FOO}$1
!insertmacro ModifySectionHack${SID_BAZ}$1
功能端

我想看看使用
SectionSetSize
的示例。我可以将其嵌入每个节中,还是需要在其他地方编写脚本,以循环浏览节名列表,获得大小,除以2,然后设置大小?我对NSIS的经验有限,不想一起破解一个可能不可靠的解决方案。在到达UI中可见的位置之前,必须使用SectionSetSize。组件页面的预回调是一个很好的位置,但是如果您需要在其他位置调整节大小,您可能希望将其放在.onInit中。