【问题标题】:NSIS optional custom pagesNSIS 可选自定义页面
【发布时间】:2021-04-21 07:28:42
【问题描述】:

我想在安装过程结束时在 NSIS 中创建一个复选框,选中后,它将引导用户到一个自定义页面,该页面有一堆单选框,引导用户到另一个自定义页面(取决于选择) 等等。

我知道如何使用 nsDialogs 创建自定义页面,但我无法弄清楚多个可选自定义页面背后的逻辑。任何帮助表示赞赏。

或者,有没有办法创建多个默认禁用的复选框/单选框组(第一个除外),并且仅在用户选择组中的框时才激活?

【问题讨论】:

  • “安装过程结束时”复选框在哪里?
  • 我的意思是自定义页面中的复选框
  • 但是你的想法(在一个部分中做)很酷,所以谢谢。

标签: installation nsis


【解决方案1】:

在页面 Pre-callback 中调用 Abort 跳过页面。然后,您所要做的就是跟踪要显示的页面以及要跳过的页面:

!include nsDialogs.nsh
!include LogicLib.nsh

Section "Do custom page thing" SID_DOCUSTOMPAGES
SectionEnd

Page Components
Page InstFiles
Page Custom Cust1Pre Cust2Next
Page Custom CustAPre
Page Custom CustBPre

Var WantedPage

Function Cust1Pre
${IfNot} ${SectionIsSelected} ${SID_DOCUSTOMPAGES}
    StrCpy $WantedPage ""
    Abort
${EndIf}
nsDialogs::Create 1018
Pop $0
${NSD_CreateRadioButton} 0 30u 100% 10u "Page A"
Pop $1
${NSD_Check} $1
${NSD_CreateRadioButton} 0 40u 100% 10u "Page B"
Pop $2
nsDialogs::Show
FunctionEnd

Function Cust2Next
${NSD_GetState} $1 $0
${If} $0 <> ${BST_UNCHECKED}
    StrCpy $WantedPage A
${Else}
    StrCpy $WantedPage B
${EndIf}
FunctionEnd

Function CustAPre
${IfNotThen} $WantedPage == A ${|} Abort ${|}
GetDlgItem $0 $hWndParent 1
SendMessage $0 ${WM_SETTEXT} "" "STR:$(^CloseBtn)" ; Change button text since page B is skipped and we are now the last page
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page A"
Pop $0
nsDialogs::Show
FunctionEnd

Function CustBPre
${IfNotThen} $WantedPage == B ${|} Abort ${|}
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page B"
Pop $0
nsDialogs::Show
FunctionEnd

您可以通过使用“A”或“B”的单个页面来摆脱 WM_SETTEXT 解决方法:

!include nsDialogs.nsh
!include LogicLib.nsh

Section "Do custom page thing" SID_DOCUSTOMPAGES
SectionEnd

Page Components
Page InstFiles
Page Custom Cust1Pre Cust2Next
Page Custom CustAOrBPre

Var WantedPage

Function Cust1Pre
${IfNot} ${SectionIsSelected} ${SID_DOCUSTOMPAGES}
    StrCpy $WantedPage ""
    Abort
${EndIf}
nsDialogs::Create 1018
Pop $0
${NSD_CreateRadioButton} 0 30u 100% 10u "Page A"
Pop $1
${NSD_Check} $1
${NSD_CreateRadioButton} 0 40u 100% 10u "Page B"
Pop $2
nsDialogs::Show
FunctionEnd

Function Cust2Next
${NSD_GetState} $1 $0
${If} $0 <> ${BST_UNCHECKED}
    StrCpy $WantedPage A
${Else}
    StrCpy $WantedPage B
${EndIf}
FunctionEnd

Function CustAPre
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page A"
Pop $0
nsDialogs::Show
FunctionEnd

Function CustBPre
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page B"
Pop $0
nsDialogs::Show
FunctionEnd

Function CustAOrBPre
${If} $WantedPage == A
    Call CustAPre
${Else}
    Call CustBPre
${EndIf}
FunctionEnd

只有一个带有禁用选项的页面当然更好:

!include nsDialogs.nsh
!include LogicLib.nsh

Page InstFiles
Page Custom CustPre

Function CustPre
nsDialogs::Create 1018
Pop $0

${NSD_CreateCheckBox} 10 30u 100% 10u "Enable other stuff"
Pop $0
${NSD_OnClick} $0 OnCheckChange

${NSD_CreateRadioButton} 10 50u 100% 10u "Foo"
Pop $1
${NSD_AddStyle} $1 ${WS_GROUP}
${NSD_Check} $1
${NSD_CreateRadioButton} 10 70u 100% 10u "Bar"
Pop $2
${NSD_RemoveStyle} $2 ${WS_TABSTOP}

Push $0
Call OnCheckChange ; Enforce state
nsDialogs::Show
FunctionEnd

!macro SetRadiosEnabled state
EnableWindow $1 ${state}
EnableWindow $2 ${state}
!macroend
Function OnCheckChange
Pop $0
${NSD_GetState} $0 $0
${If} $0 <> ${BST_UNCHECKED}
    !insertmacro SetRadiosEnabled 1
${Else}
    !insertmacro SetRadiosEnabled 0
${EndIf}
FunctionEnd

【讨论】:

  • 一如既往的好答案。非常感谢。顺便说一句,我知道这超出了原始问题的范围,但是既然您在这里,有没有办法显示仅在选中某个单选按钮时才启用(并记录其值)的禁用文本框?
  • 您只需将这些部分放在一起:${NSD_GetState} 和 EnableWindow/ShowWindow。
  • 还有一件事(对不起,如果我打扰你了)...有没有办法使用 CreateShortcut 以便快捷方式“目标”不包含任何路径?我想为 PATH 环境中的应用程序创建一个快捷方式,所以我不需要指定它的完整路径,但我似乎找不到方法来做到这一点(即使我可以手动完成)。如果我将命令指定为目标文件,它将以快捷方式的路径为前缀,如果我将目标留空并将命令放入参数中,则快捷方式指向“这台电脑”。
  • 没关系,我决定使用应用程序的完整路径
  • 快捷方式并不真正支持相对目标。 NSIS 使用普通的 Windows 快捷方式 API,这意味着 Windows 可能会在你背后稍微改变目标誓言。
猜你喜欢
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 2013-11-09
  • 2012-10-05
相关资源
最近更新 更多