使用 NSIS 进行条件安装

Conditional Installation with NSIS

我需要制作一个安装程序,如果相关软件已经安装,它也将充当 repair/uninstall 程序。

我设法制作了一个自定义页面,用于检查程序是否存在并根据该页面显示按钮(创建注册表项仅用于测试目的,应包含在安装过程中)。

例如,如果未安装程序,则会显示安装按钮。

这是执行此操作的代码:

Page Custom MyCustomPage

var button
var buttonRepair
var buttonUninstall
var dialog

Function MyCustomPage
ReadRegStr $R0 HKLM ${P_DIR_REGKEY} "Version"
${If} ${Errors}
    Goto NotInstalled
${Else}
    Goto Installed
${EndIf}

    NotInstalled:
        nsDialogs::Create 1018
        ;Pop $dialog
        ${NSD_CreateButton} 25% 25% 50% 50% "Install"
        Pop $button
        EnableWindow $button 1 # start out disabled
        WriteRegStr HKLM ${P_DIR_REGKEY} "Version" ${P_VERSION}
        WriteRegStr HKLM ${P_DIR_REGKEY} "" "$INSTDIR\asd.exe"
        nsDialogs::Show
        ${NSD_OnClick} $button ManageInstall
        Goto MyEnd
    Installed:
        nsDialogs::Create 1018
        Pop [=10=]
        ${NSD_CreateButton} 12% 12% 25% 25% "Repair"
        Pop $buttonRepair
        ${NSD_CreateButton} 37% 12% 25% 25% "Uninstall"
        Pop $buttonUninstall
        EnableWindow $button 1 # start out disabled
        EnableWindow $button2 1
        ${NSD_OnClick} $buttonRepair ManageRepair
        ${NSD_OnClick} $buttonUninstall ManageUninstall
        nsDialogs::Show
        Goto MyEnd
    MyEnd:
        Quit
FunctionEnd

Function ManageInstall
    MessageBox MB_OK "Installation"
FunctionEnd

Function ManageRepair
    MessageBox MB_OK "Repair"
FunctionEnd

Function ManageUninstall
    MessageBox MB_OK "Uninstallation"
FunctionEnd

问题是它都是由函数管理的,我无法在其中声明新的页面宏,因此我无法继续通过部分进行正确安装。

我应该如何管理安装程序要采取的不同操作,以便能够像正常安装一样制作用户友好的页面?

我是否应该为每个操作都使用自定义页面,因为这听起来有点挑剔和复杂?

我建议您创建一个名为 "ACTION" 的变量,并在用户单击某个选项时设置它的值。然后,跳转到下一页。像这样:

# http://nsis.sourceforge.net/Go_to_a_NSIS_page
Function RelGotoPage
  IntCmp $R9 0 0 Move Move
    StrCmp $R9 "X" 0 Move
      StrCpy $R9 "120"

  Move:
  SendMessage $HWNDPARENT "0x408" "$R9" ""
FunctionEnd

Function GotoNextPage
    StrCpy $R9 "1"
    Call RelGotoPage
FunctionEnd


Function ManageRepair
    StrCpy $ACTION "repair"
    Call GotoNextPage
    Abort
FunctionEnd

然后,在每个页面的"pre"功能上,您需要检查它是否必须显示:

Function repairpage
    # Do not display this page unless user selected Repair.
    ${if} "$ACTION" != "repair"
        Abort
    $[EndIf}

    ....
FunctionEnd