RelGotoPage 函数转到下一页而不是返回

RelGotoPage function goes to next page instead of going back

我当前在安装程序中定义的页面顺序是:

!insertmacro MUI_PAGE_WELCOME                             ; Welcome page
!insertmacro MUI_PAGE_DIRECTORY                           ; Select a directory
!define MUI_PAGE_CUSTOMFUNCTION_PRE CheckInstallDirectory ; Check selected directory
!insertmacro MUI_PAGE_COMPONENTS                          ; Choose install components
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipLicense           ; Component1's check before license page
!insertmacro MUI_PAGE_LICENSE "license.txt"               ; Component1's license
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipLicenseForComp2   ; Component2's check before license page
!insertmacro MUI_PAGE_LICENSE "License2.txt"              ; Component2's license
!insertmacro CUSTOM_PAGES                                 ; Custom install pages
!insertmacro MUI_PAGE_INSTFILES                           ; Install components' files
!insertmacro MUI_PAGE_FINISH                              ; Finish page

在下面定义的 CheckInstallDirectory 函数中,它检查最终用户是否选择了一个已经包含 .exe 的目录,否则安装程序会安装该 .exe。

如果目录存在,将向用户显示带有“确定”和“取消”按钮的弹出消息框。 “确定”选项应跳过接下来的几页并转到 MUI_PAGE_INSTFILES 页。 “取消”选择应该 return 用户到 MUI_PAGE_DIRECTORY 页面。

Function CheckInstallDirectory

  IfFileExists "$INSTDIR\Component1.exe" file_found end_of_check
  file_found:
  Var /GLOBAL ver_
  ${GetFileVersion} "$INSTDIR\Component1.exe" $ver_
  StrCpy [=11=] $ver_ 1 ; Determine the major version of the installed exe (1st char of the returned string)
  StrCpy  $ver_1 1 ; Determine the major version of the exe we are installing (1st char of the returned string)
  ${If} [=11=] == 
    ; The major version between .exe's is the same
    MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "A copy of this software is already installed in the selected directory.$\nSelect $\"OK$\" if you would like to update the software to the latest version.$\nOtherwise select $\"Cancel$\" to go back and select a different installation directory." IDOK OK IDCANCEL CANCEL
    OK:
      ; User selected to update this software - continue with the installation like normal
      StrCpy $R9 "7" ; Skip to the installation page
      Call RelGotoPage
      goto end_of_check
    CANCEL:
      StrCpy $R9 "-1" ; Go back to directory selection page
      Call RelGotoPage
      goto end_of_check
  ${Else}
    ; The major version between the .exe's is NOT the same - cannot update
    MessageBox MB_OK "A copy of this software is already installed in the selected directory.$\nIt is not part of the latest major-version group and cannot be updated. To update this installation, uninstall and use the installer to install the latest version.$\nOtherwise, select$\"OK$\" to go back and select a different installation directory."
    StrCpy $R9 "-1" ; Go back to directory selection page
    Call RelGotoPage
    goto end_of_check
  ${EndIf}
  end_of_check:

FunctionEnd

我找到了 NSIS 关于如何跨安装程序页面移动的描述 here

Function RelGotoPage
  IntCmp $R9 0 0 Move Move
    StrCmp $R9 "X" 0 Move
      StrCpy $R9 "120"

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

出现的问题是 StrCpy $R9 "7" 确实成功跳到了 MUI_PAGE_INSTFILES 页面。然而,StrCpy $R9 "-1" 不会 return 到上一页(应该是 MUI_PAGE_DIRECTORY)。相反,如果在该弹出消息中选择“取消”,安装程序将转到下一页,MUI_PAGE_COMPONENTS。

这里哪里不对? 有没有更好的方法达到预期效果?

真诚感谢任何帮助!谢谢!

在页面预回调中,页面未完全加载,我认为这就是 -1 无法正常工作的原因。如果您使用 MUI_PAGE_CUSTOMFUNCTION_SHOW -1 确实有效,但正确的方法是阻止页面更改:

!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME                             ; Welcome page
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE CheckInstallDirectory
!insertmacro MUI_PAGE_DIRECTORY
...

Function CheckInstallDirectory
;Snipped
    MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "A copy of this software is already installed in the selected directory.$\nSelect $\"OK$\" if you would like to update the software to the latest version.$\nOtherwise select $\"Cancel$\" to go back and select a different installation directory." IDOK OK IDCANCEL CANCEL
    OK:
      ; User selected to update this software - continue with the installation like normal
      StrCpy $R9 "7" ; Skip to the installation page
      Call RelGotoPage
      goto end_of_check
    CANCEL:
      Abort
;Snipped
  end_of_check:
FunctionEnd