0

我有以下 NSIS 安装类型:

InstType "X (推荐)"
InstType "/CUSTOMSTRING=Y (高级模式)"
InstType /COMPONENTSONLYONCUSTOM

这个想法是安装“X”应该静默安装所有组件,而安装“Y”应该只安装已选择的组件。默认情况下,安装“Y”的组件应全部取消选择。这是我无法实现的。

我已经尝试了很多不同的方案来取消选择安装“Y”的所有组件,但由于某种原因,NSIS 将始终选择“X”作为“Y”的默认选择。由于已为“X”选择了所有组件,安装“Y”将默认选择所有组件。

在这种情况下,如何确保默认取消选择所有组件安装“Y”?

4

1 回答 1

2

/CUSTOMSTRING InstType 是特殊的,因此您可能会在这里稍微改变规则,自定义的目的是让用户挑选部分并最终得到与您预定义的任何 InstType 不同的东西。它实际上没有默认值,它基于用户选择的先前 InstType(在您的情况下始终为 X)。

!include LogicLib.nsh
!include Sections.nsh
!include WinMessages.nsh

Page Components
Page InstFiles

!define ITSIN_X 1 ; SectionIn ID's are 1 based
InstType "X (recommended)"
InstType "/CUSTOMSTRING=Y (advanced mode)" ; The "special" custom InstType
InstType /COMPONENTSONLYONCUSTOM

Section "A" SID_A
SectionIn ${ITSIN_X}
DetailPrint a
SectionEnd

Section "B" SID_B
SectionIn ${ITSIN_X}
DetailPrint b
SectionEnd

Function .onSelChange
/*
UNDOCUMENTED HACK!
We are going to check if the current InstType is the custom type even if the current section "selection" matches another InstType (GetCurInstType returns non-custom if possible)
*/
FindWindow $9 "#32770" "" $HWNDPARENT
FindWindow $9 "ComboBox" "" $9
SendMessage $9 ${CB_GETCURSEL} 0 0 $0
SendMessage $9 ${CB_GETITEMDATA} $0 0 $0
${If} $0 = ${NSIS_MAX_INST_TYPES} ; The custom InstType?
${AndIf} $1 <> $0 ; Only do the unselect hack on InstType changes (BUGBUG: Should really set $1 to something in the page create/show callback)
!if 1 ; If you only have a few sections you can just use their ID
    !insertmacro UnselectSection ${SID_A}
    !insertmacro UnselectSection ${SID_B}
!else ; ...or use a loop if you are lazy
    StrCpy $2 0
    ClearErrors
    loop:
        SectionGetFlags $2 $3
        IfErrors end
        !insertmacro UnselectSection $2 ; You could check SectionGetText if you need to skip hidden sections here
        IntOp $2 $2 + 1
        Goto loop
    end:
!endif
${EndIf}
StrCpy $1 $0 ; Save the current InstType so we can tell if it changes
FunctionEnd
于 2013-10-19T02:55:51.017 回答