NSIS 在一页上读取 2 个目录路径

NSIS reading 2 directory paths on 1 page

使用 NSIS 对话框设计器,我设计了一个页面,其中有 2 个组框,每个组框都有一个目录输入控件。

InstallLocation.nsddef如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--
This file was created by NSISDialogDesigner 1.5.0.0
https://coolsoft.altervista.org/nsisdialogdesigner
Do not edit manually!
-->
<Dialog Name="InstallLocation" Title="Install Locations" Subtitle="Select the paths">
  <CreateFunctionCustomScript>#Set currently saved values for the fields
${NSD_SetText} $hCtl_InstallLocation_FirstInstallDir_Txt $R0
${NSD_SetText} $hCtl_InstallLocation_SecondInstallDir_Txt $R1</CreateFunctionCustomScript>
  <GroupBox Name="GroupBox2" Location="27, 148" Size="376, 68" Text="Select the second path. eg C:\PQR" TabIndex="0">
    <DirRequest Name="SecondInstallDir" Location="6, 28" Size="342, 20" TabIndex="0" ButtonText="Browse..." ButtonWidth="70" />
  </GroupBox>
  <Label Name="Label1" Location="27, 8" Size="424, 38" Text="Select both the paths." TabIndex="1" />
  <GroupBox Name="GroupBox1" Location="27, 64" Size="376, 68" Text="Select the first path. e.g. C:\ABC" TabIndex="2">
    <DirRequest Name="FirstInstallDir" Location="6, 28" Size="342, 20" TabIndex="0" ButtonText="Browse..." ButtonWidth="70" />
  </GroupBox>
</Dialog>

对应的InstallLocation.nsdinc如下:

; =========================================================
; This file was generated by NSISDialogDesigner 1.5.0.0
; https://coolsoft.altervista.org/nsisdialogdesigner
;
; Do not edit it manually, use NSISDialogDesigner instead!
; =========================================================

; handle variables
Var hCtl_InstallLocation
Var hCtl_InstallLocation_GroupBox2
Var hCtl_InstallLocation_SecondInstallDir_Txt
Var hCtl_InstallLocation_SecondInstallDir_Btn
Var hCtl_InstallLocation_Label1
Var hCtl_InstallLocation_GroupBox1
Var hCtl_InstallLocation_FirstInstallDir_Txt
Var hCtl_InstallLocation_FirstInstallDir_Btn


; dialog create function
Function fnc_InstallLocation_Create
  
  ; === InstallLocation (type: Dialog) ===
  nsDialogs::Create 1018
  Pop $hCtl_InstallLocation
  ${If} $hCtl_InstallLocation == error
    Abort
  ${EndIf}
  !insertmacro MUI_HEADER_TEXT "Install Locations" "Select the paths"
  
  ; === GroupBox2 (type: GroupBox) ===
  ${NSD_CreateGroupBox} 18u 91u 247u 42u "Select the second path. eg C:\PQR"
  Pop $hCtl_InstallLocation_GroupBox2
  
  ; === SecondInstallDir_Txt (type: Text) ===
  ${NSD_CreateText} 22u 108u 178u 12u ""
  Pop $hCtl_InstallLocation_SecondInstallDir_Txt
  
  ; === SecondInstallDir_Btn (type: Button) ===
  ${NSD_CreateButton} 201u 108u 46u 12u "Browse..."
  Pop $hCtl_InstallLocation_SecondInstallDir_Btn
  ${NSD_OnClick} $hCtl_InstallLocation_SecondInstallDir_Btn fnc_hCtl_InstallLocation_SecondInstallDir_Click
  
  ; === Label1 (type: Label) ===
  ${NSD_CreateLabel} 18u 5u 279u 23u "Select both the paths."
  Pop $hCtl_InstallLocation_Label1
  
  ; === GroupBox1 (type: GroupBox) ===
  ${NSD_CreateGroupBox} 18u 39u 247u 42u "Select the first path. e.g. C:\ABC"
  Pop $hCtl_InstallLocation_GroupBox1
  
  ; === FirstInstallDir_Txt (type: Text) ===
  ${NSD_CreateText} 22u 57u 178u 12u ""
  Pop $hCtl_InstallLocation_FirstInstallDir_Txt
  
  ; === FirstInstallDir_Btn (type: Button) ===
  ${NSD_CreateButton} 201u 57u 46u 12u "Browse..."
  Pop $hCtl_InstallLocation_FirstInstallDir_Btn
  ${NSD_OnClick} $hCtl_InstallLocation_FirstInstallDir_Btn fnc_hCtl_InstallLocation_FirstInstallDir_Click
  
  ; CreateFunctionCustomScript
  #Set currently saved values for the fields
  ${NSD_SetText} $hCtl_InstallLocation_FirstInstallDir_Txt $R0
  ${NSD_SetText} $hCtl_InstallLocation_SecondInstallDir_Txt $R1
  
  
FunctionEnd

; dialog show function
Function fnc_InstallLocation_Show
  Call fnc_InstallLocation_Create
  nsDialogs::Show
FunctionEnd


; onClick handler for DirRequest Button $hCtl_InstallLocation_SecondInstallDir_Btn
Function fnc_hCtl_InstallLocation_SecondInstallDir_Click
    Pop $R0
    ${If} $R0 == $hCtl_InstallLocation_SecondInstallDir_Btn
        ${NSD_GetText} $hCtl_InstallLocation_SecondInstallDir_Txt $R0
        nsDialogs::SelectFolderDialog /NOUNLOAD "" "$R0"
        Pop $R0
        ${If} "$R0" != "error"
            ${NSD_SetText} $hCtl_InstallLocation_SecondInstallDir_Txt "$R0"
        ${EndIf}
    ${EndIf}
FunctionEnd

; onClick handler for DirRequest Button $hCtl_InstallLocation_FirstInstallDir_Btn
Function fnc_hCtl_InstallLocation_FirstInstallDir_Click
    Pop $R0
    ${If} $R0 == $hCtl_InstallLocation_FirstInstallDir_Btn
        ${NSD_GetText} $hCtl_InstallLocation_FirstInstallDir_Txt $R0
        nsDialogs::SelectFolderDialog /NOUNLOAD "" "$R0"
        Pop $R0
        ${If} "$R0" != "error"
            ${NSD_SetText} $hCtl_InstallLocation_FirstInstallDir_Txt "$R0"
        ${EndIf}
    ${EndIf}
FunctionEnd

正如您所注意到的,当我从安装程序将从中读取的属性文件中预填充值时,我将 CreateFunctionCustomScript 设置如下:

  ${NSD_SetText} $hCtl_InstallLocation_FirstInstallDir_Txt $R0
  ${NSD_SetText} $hCtl_InstallLocation_SecondInstallDir_Txt $R1

在我的 .nsi 脚本中,我试图将上述路径读入局部变量,例如:

Page custom InstallLocation_Show InstallLocation_Leave
Function InstallLocation_Show
    #Initialise temp variables
    StrCpy $R0 $firstInstallPath
    StrCpy $R1 $secondInstallPath
    Call fnc_InstallLocation_Show
FunctionEnd
Function InstallLocation_Leave
    ${NSD_GetText} hCtl_InstallLocation_FirstInstallDir_Txt $R0
    ${NSD_GetText} hCtl_InstallLocation_SecondInstallDir_Txt $R1
    StrCpy $firstInstallPath $R0
    StrCpy $secondInstallPath $R1
    #Ensure values are entered in both fields
    StrCpy $message ""
    ${if} $R0 == ""
    ${OrIf} $R1 == ""
        StrCpy $message "$message both folders are required $\r$\n"
    ${EndIf}
    ${if} $message != ""
        MessageBox MB_OK|MB_ICONQUESTION $message
        Abort
    ${EndIf}
FunctionEnd

因此,除非用户不 select 两条路径,否则将不断弹出消息 both folders are required

但是,它并没有像我期望的那样工作。

即使在我 select 两条路径之后,消息框仍然弹出,我无法 select Next 转到下一页。

我知道这是因为两个点击函数都在 $R0 中存储值。但是我无法弄清楚我应该在对话框设计器中做什么,以便第一条路径的值进入 $R0 而第二条路径的值进入 $R1 ?

现在已经花了几个小时试图找出在对话框设计器中做什么或如何修改我的 .nsi 逻辑以正确读取两个路径并使我的验证弹出窗口正确运行。

${NSD_GetText} hCtl_InstallLocation_FirstInstallDir_Txt $R0 缺少 HWND 变量的 $!试试 ${NSD_GetText} $hCtl_InstallLocation_FirstInstallDir_Txt $R0.