当我单击自定义页面右上角的 "Finish" 按钮或关闭按钮时,页面未使用 NSIS 关闭

When I am clicking on "Finish" button or close button at the top right corner of the custom page, page is not closing using NSIS

我遇到了一个奇怪的问题,我添加了一个新的自定义页面 (MyAbruptPage)。单击此自定义页面右上角的“完成”按钮或关闭按钮时,页面没有关闭。

场景:

安装软件时,如果出现问题并且安装未正确完成,它会显示来自 INSTFILES 页面的 MessageBox。单击消息框上的“确定”后,它将导航到“突然”页面。在 Abrupt Page 中它显示“完成”按钮,但是当单击“完成”时页面没有关闭而是显示弹出消息(你确定要关闭吗?)。即使当我点击右上角的关闭按钮时,我也会收到相同的弹出消息。我不想要该消息,单击“完成”按钮时应关闭对话框。

观察:

我认为问题出在页面的顺序上。因为我在这里使用了两个自定义页面(MyInfoPage 和 MyAbruptPage)。

如果我用 MyAbruptPage 替换第一页 (MyInfoPage)。然后我在突然页面中单击“完成”按钮时没有看到任何问题。

下面是我显示页面及其顺序的代码片段:

Page Custom MyInfoPage   ; First Custom page

!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!insertmacro MUI_PAGE_WELCOME

!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!insertmacro MUI_PAGE_LICENSE

!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!insertmacro MUI_PAGE_DIRECTORY

Page Custom MyAbruptPage    ; Second Custom Page

!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave
!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_PAGE_FINISH

;下面是我的 Abrupt 页面代码

Function AbruptShow
StrCpy $IsOnAbruptPage 1
GetDlgItem [=12=] $HWNDPARENT 3
ShowWindow [=12=] 0 
FunctionEnd

Function AbruptLeave
StrCpy $IsOnAbruptPage 0
FunctionEnd

Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem [=12=] $HWNDPARENT 1
ShowWindow [=12=] 0 ; Hide Next button

GetDlgItem [=12=] $HWNDPARENT 3
ShowWindow [=12=] 0 ; Hide Back button

GetDlgItem [=12=] $HWNDPARENT 2
${NSD_SetText} [=12=] "Finish"

nsDialogs::Create 1044
Pop [=12=]
${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "$(AbruptTitle)"
    Pop $AbruptPageTitle
    ;SetCtlColors $InterruptPageTitle "" "${MUI_BGCOLOR}"
    CreateFont $AbruptPageFont "$(^Font)" "12" "700"
    SendMessage $AbruptPageTitle ${WM_SETFONT} $AbruptPageFont 0

 ${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "$(AbruptText)"
    Pop $AbruptPageText
 Pop [=12=]

nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd

下面是部分,从这里弹出消息框并导航到“突然”屏幕:

;!insertmacro MUI_LANGUAGE "English" 

Section MySection

SetOutPath $INSTDIR

MessageBox MB_OK|MB_ICONEXCLAMATION "Installation hasn't done properly" IDOK

Call AbruptLeave
        SendMessage $HWNDPARENT 0x408 -1 ""
        Abort 

SectionEnd

;下面是自定义页面“MyInfoPage”的代码

Function MyInfoPage

${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem [=14=] $HWNDPARENT 1
ShowWindow [=14=] 0 ; Hide Next button
GetDlgItem [=14=] $HWNDPARENT 2
${NSD_SetText} [=14=] "Finish"

nsDialogs::Create 1044
Pop [=14=]

${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "$(InterruptTitle)"
Pop $InterruptPageTitle   

${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "$(InterruptText)"
Pop $InterruptPageText

nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd

Function WelShow
StrCpy $PageId 1
GetDlgItem [=14=] $HWNDPARENT 3
ShowWindow [=14=] 0 ; Hide Back button
FunctionEnd

Function onAbort
${If} $PageId <> 0
    ${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to close?" IDYES `
        SendMessage $HWNDPARENT 0x408 -$PageId ""
    ${EndIf}
    Abort
${EndIf}
FunctionEnd

我尝试过更改页面的顺序,每次我都在两个自定义页面中观察到不同的行为。请帮我解决这个问题?以及实现此功能的正确方法。

提前谢谢你...

完整代码如下,正在编译中:

Var PageId
Var PrintBtn
Var Image
Var ImageHandle

Var MyInfoPageTitle
Var MyInfoPageFont
var MyInfoPageText
var IsOnAbruptPage
Var AbruptPageTitle
Var AbruptPageFont
var AbruptPageText

!define MUI_CUSTOMFUNCTION_ABORT onAbort

!include "MUI2.nsh"
!include x64.nsh

Name "MyApp"

OutFile "MyApp.exe"

InstallDir "$PROGRAMFILES32\MyApp"

InstallDirRegKey HKLM "Software\MyApp" "Install_Dir"

RequestExecutionLevel admin

!include LogicLib.nsh

;--------------------------------

Page Custom MyInfoPage


  !define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow

  !define MUI_TEXT_WELCOME_INFO_TITLE $(welcometitle)
  !define MUI_TEXT_WELCOME_INFO_TEXT $(welcometext)

  !insertmacro MUI_PAGE_WELCOME
  
  !define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback

  !define MUI_LICENSEPAGE_CHECKBOX ""
  !define MUI_INNERTEXT_LICENSE_BOTTOM ""
  !define MUI_INNERTEXT_LICENSE_TOP ""
  !define MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX ""
  
  !define MUI_TEXT_LICENSE_TITLE $(licensetitle)
  !define MUI_TEXT_LICENSE_SUBTITLE $(licensesubtitle)
  !define MUI_LICENSEPAGE_CHECKBOX_TEXT $(licensecheckboxtext)
  
  !insertmacro MUI_PAGE_LICENSE "C:\Program Files (x86)\NSIS\Docs\Modern UI 2\license.txt"

 !define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
 
!define MUI_DIRECTORYPAGE_TEXT_TOP $(mydirtoptext)
!define MUI_TEXT_DIRECTORY_TITLE $(mydirtitle)
!define MUI_TEXT_DIRECTORY_SUBTITLE $(mydirsubtitle)

  !insertmacro MUI_PAGE_DIRECTORY
  
  Page Custom MyAbruptPage   

!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave


  !insertmacro MUI_PAGE_INSTFILES
   
  !define MUI_TEXT_FINISH_INFO_TITLE $(Finishpagetitle)
  !define MUI_TEXT_FINISH_INFO_TEXT $(Finishpagesubtitle)

  !define MUI_FINISHPAGE_RUN ""
  !define MUI_FINISHPAGE_RUN_TEXT $(FinishonlineReg)

  !insertmacro MUI_PAGE_FINISH

  !insertmacro MUI_UNPAGE_INSTFILES
  
 ;--------------------------------
  !insertmacro MUI_LANGUAGE "English" 

Function .onInit
InitPluginsDir

FunctionEnd
Function MyDirectoryShowCallback
StrCpy $PageId 3

GetDlgItem [=15=] $hwndparent 1 ; 
SendMessage [=15=] ${WM_SETTEXT} 0 `STR:$(^NextBtn)`
FunctionEnd

Function MyLicenseShowCallback

StrCpy $PageId 2

GetDlgItem [=15=] $hwndparent 2 
System::Call *(i,i,i,i)p.r1
System::Call 'USER32::GetWindowRect(pr0,pr1)'
System::Call *(i.r2,i.r3,i.r4,i.r5)
IntOp   -  ;height
IntOp   -  ;width
System::Call 'USER32::ScreenToClient(p$hwndparent,pr1)'
System::Call *(i.r2,i.r3)
System::Free 
IntOp   / 5
System::Call 'USER32::CreateWindowEx(i 0,t "Button",t "Print",i ${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},i r2,i r3,i r4,i r5,p $hwndparent,p 0x666,p 0,p 0)p.r0'
StrCpy $PrintBtn [=15=]
SendMessage $hwndparent ${WM_GETFONT} 0 0 
SendMessage [=15=] ${WM_SETFONT}  1
ButtonEvent::AddEventHandler 0x666 [=15=]
FunctionEnd

Function WelShow
StrCpy $PageId 1
GetDlgItem [=15=] $HWNDPARENT 3
ShowWindow [=15=] 0 
FunctionEnd

Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem [=15=] $HWNDPARENT 1
ShowWindow [=15=] 0 
GetDlgItem [=15=] $HWNDPARENT 2
${NSD_SetText} [=15=] "Finish"

nsDialogs::Create 1044
Pop [=15=]

!define MUI_WELCOMEPAGE_TITLE_HEIGHT 38
!define /math MUI_WELCOMEPAGE_TEXT_TOP 17 + ${MUI_WELCOMEPAGE_TITLE_HEIGHT}

${NSD_CreateLabel} 120u 10u 195u 28u "Setup Wizard was interrupted"

    Pop $MyInfoPageTitle
    CreateFont $MyInfoPageFont "$(^Font)" "12" "700"
    SendMessage $MyInfoPageTitle ${WM_SETFONT} $MyInfoPageFont 0
     ${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "Setup Wizard was interrupted"
    Pop $MyInfoPageText

Pop [=15=]

nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd

Function onAbort
${If} $PageId <> 0
    ${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to CANCEL" IDYES `
        SendMessage $HWNDPARENT 0x408 -$PageId ""
    ${EndIf}
    Abort
${EndIf}
FunctionEnd


Function AbruptShow
StrCpy $IsOnAbruptPage 1
GetDlgItem [=15=] $HWNDPARENT 3
ShowWindow [=15=] 0 
FunctionEnd

Function AbruptLeave
StrCpy $IsOnAbruptPage 0
FunctionEnd

Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem [=15=] $HWNDPARENT 1
ShowWindow [=15=] 0 

GetDlgItem [=15=] $HWNDPARENT 3
ShowWindow [=15=] 0 

GetDlgItem [=15=] $HWNDPARENT 2

${NSD_SetText} [=15=] "Finish"

nsDialogs::Create 1044
Pop [=15=]

${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "Setup Wizard ended prematurely"
    Pop $AbruptPageTitle

    CreateFont $AbruptPageFont "$(^Font)" "12" "700"
    SendMessage $AbruptPageTitle ${WM_SETFONT} $AbruptPageFont 0

 ${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "Setup Wizard ended prematurely"
    Pop $AbruptPageText
 Pop [=15=]

nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd


  SectionIn RO

SetOutPath $INSTDIR

MessageBox MB_OK|MB_ICONEXCLAMATION "There is an installation failure. Aborting the installation process" IDOK

Call AbruptLeave
        SendMessage $HWNDPARENT 0x408 -1 ""
        Abort

SectionEnd
  
Section "Uninstall"

SectionEnd

您看到的 MessageBox 来自您自己在 onAbort 函数中的代码!

你正在做的事实

!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave

表明您不了解自定义页面的工作原理。

要使您的特殊中止页面退出而无需进一步操作,您只需在该页面上时在 onAbort 函数中不执行任何操作即可:

Var PageId
var IsOnAbruptPage
!define MUI_CUSTOMFUNCTION_ABORT onAbort
!include "MUI2.nsh"
!include LogicLib.nsh
Name "MyApp"

#OutFile "MyApp.exe"
InstallDir "$temp\MyApp"
#RequestExecutionLevel admin
OutFile Test.exe
RequestExecutionLevel user


;--------------------------------
Page Custom MyInfoPage
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyAbruptPage 
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
!insertmacro MUI_LANGUAGE "English" 

Function MyDirectoryShowCallback
StrCpy $PageId 3
GetDlgItem [=11=] $hwndparent 1 ; 
SendMessage [=11=] ${WM_SETTEXT} 0 `STR:$(^NextBtn)`
FunctionEnd

Function MyLicenseShowCallback
StrCpy $PageId 2
FunctionEnd

Function WelShow
StrCpy $PageId 1
GetDlgItem [=11=] $HWNDPARENT 3
ShowWindow [=11=] 0 
FunctionEnd


Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem [=11=] $HWNDPARENT 1
ShowWindow [=11=] 0 
GetDlgItem [=11=] $HWNDPARENT 2
${NSD_SetText} [=11=] "Finish"
nsDialogs::Create 1044
Pop [=11=]
${NSD_CreateLabel} 120u 10u 195u 28u "Setup Wizard was interrupted"
Pop [=11=]
nsDialogs::Show
FunctionEnd

Function onAbort
${If} $IsOnAbruptPage <> 0 ; If on aborted page
    Return                 ; allow simple exit
${EndIf}
${If} $PageId <> 0
    ${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to CANCEL" IDYES `
        SendMessage $HWNDPARENT 0x408 -$PageId ""
    ${EndIf}
    Abort
${EndIf}
FunctionEnd

Function GoToAbruptPage
StrCpy $IsOnAbruptPage 1
SendMessage $HWNDPARENT 0x408 -1 ""
Abort
FunctionEnd

Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem [=11=] $HWNDPARENT 1
ShowWindow [=11=] 0 
GetDlgItem [=11=] $HWNDPARENT 3
ShowWindow [=11=] 0 
GetDlgItem [=11=] $HWNDPARENT 2
${NSD_SetText} [=11=] "Finish"
nsDialogs::Create 1044
Pop [=11=]
${NSD_CreateLabel} 120u 10u 195u 20u "Setup Wizard ended prematurely"
Pop [=11=]
${NSD_CreateLabel} 120u 120u 195u 20u "Setup Wizard ended prematurely"
Pop [=11=]
nsDialogs::Show
FunctionEnd

;--------------------------------
Section "$(^Name) (required)"
SectionIn RO
SetOutPath $INSTDIR

MessageBox MB_OK|MB_ICONEXCLAMATION "There is an installation failure. Aborting the installation process" IDOK
Call GoToAbruptPage
SectionEnd