Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
528 views
in Technique[技术] by (71.8m points)

nsis - RelGotoPage function goes to next page instead of going back

My current defined order of pages in the Installer are:

!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

In the CheckInstallDirectory function, which is defined below, it checks if the end-user selected a directory that already houses an .exe that would otherwise be installed by the installer.

If the directory exists, the user is presented a pop-up message box with the "OK" and "CANCEL" buttons. "OK" selection should simply skip the next few pages and go to MUI_PAGE_INSTFILES page. "CANCEL" selection should return the user to the MUI_PAGE_DIRECTORY page.

Function CheckInstallDirectory

  IfFileExists "$INSTDIRComponent1.exe" file_found end_of_check
  file_found:
  Var /GLOBAL ver_
  ${GetFileVersion} "$INSTDIRComponent1.exe" $ver_
  StrCpy $0 $ver_ 1 ; Determine the major version of the installed exe (1st char of the returned string)
  StrCpy $1 $ver_1 1 ; Determine the major version of the exe we are installing (1st char of the returned string)
  ${If} $0 == $1
    ; 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.$
Select $"OK$" if you would like to update the software to the latest version.$
Otherwise 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.$
It 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.$
Otherwise, 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

I have found NSIS's description for how to move across installer pages here.

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

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

The problem that is occurring is that StrCpy $R9 "7" does successfully skip to the MUI_PAGE_INSTFILES page. Yet, StrCpy $R9 "-1" does not return to the previous page (which should be MUI_PAGE_DIRECTORY). Instead, if "CANCEL" is selected in that pop-up message, the installer goes to the next page, MUI_PAGE_COMPONENTS.

What is incorrect here? Is there a better way to achieve the desired result?

Any help is sincerely appreciated! Thank you!

question from:https://stackoverflow.com/questions/65905423/relgotopage-function-goes-to-next-page-instead-of-going-back

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the page pre-callback the page is not fully loaded and I assume that is why -1 does not work correctly. -1 does work if you use MUI_PAGE_CUSTOMFUNCTION_SHOW but the proper way to do this is to block the page change:

!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.$
Select $"OK$" if you would like to update the software to the latest version.$
Otherwise 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...