Задать значение InstallDir в функции или как-то автоматически установить значение? - PullRequest
5 голосов
/ 03 января 2012

Я создаю установщик, используя NSIS. Этот установщик фактически устанавливает две программы в двух разных каталогах в одном и том же установщике. Я делаю это, используя страницы современного пользовательского интерфейса (MUI) и просто дважды вызывая MUI_PAGE_DIRECTORY, указывая различные начальные параметры, и захватывая каталог в макросе LEAVE. Что мне интересно, могу ли я как-то вызвать InstallDir в функции или установить значение автозаполнения каталога в функции? Или, возможно, даже вызвать функцию после того, как кнопка обзора была возвращена из?

Причина, по которой я хочу это сделать, заключается в том, что когда пользователь нажимает кнопку обзора на любой из двух страниц каталога, после того как он выбирает каталог, к нему добавляется имя конечного каталога, указанного в InstallDir.

Например: Значение InstallDir для программы 1: c: \ client Значение InstallDir для программы 2: c: \ program files \ server

пользователь нажимает кнопку просмотра программы 1 и выбирает c: \ temp, в результате получается путь c: \ temp \ client

пользователь нажимает кнопку просмотра программы 2 и выбирает c: \ независимо от полученного пути c: \ what \ server

Для справки приведем фрагменты кода того, что у меня работает, но не касается поведения кнопки автоматического добавления:

!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ClientDirectoryLeave
!insertmacro MUI_PAGE_DIRECTORY

!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ServerDirectoryLeave
!insertmacro MUI_PAGE_DIRECTORY

; Setup the page display for the client install page
Function ShowPageClient
  !insertmacro MUI_HEADER_TEXT "Client" "Client"
  !insertmacro MUI_INNERDIALOG_TEXT 1006 "Client"

  ; setup intal directory
  Push $0
  StrCpy $0 $PROGRAMFILES 2 #
  ; CLIENT_FOLDER_NAME is defined as a folder, but this would basicaly
  ; result in C:\Client as the first 2 characters of $PROGRAMFILES
  ; is the hard drive with program files installed on it
  StrCpy $INSTDIR "$0\${CLIENT_FOLDER_NAME}"
  Pop $0

    ; set the inital value of the directory text box  
    !insertmacro MUI_INNERDIALOG_TEXT 1019 $INSTDIR

    ; find and disable the directory selection box 
    ; We do not want users to type in this box
    FindWindow $R0 "#32770" "" $HWNDPARENT
    GetDlgItem $R1 $R0 1019 ;Text Box
    EnableWindow $R1 0
FunctionEnd


; Setup the page display for the server install location page
Function ShowPageServer
  !insertmacro MUI_HEADER_TEXT "Server" "Server"
  !insertmacro MUI_INNERDIALOG_TEXT 1006 "Server"

  ; setup intal directory
  ; SERVER_FOLDER_NAME is defined as a folder, but this would basicaly
  ; result in C:\Program Files\Server 
  StrCpy $INSTDIR "$PROGRAMFILES\${SERVER_FOLDER_NAME}"

  ; set the inital value of the directory text box  
  !insertmacro MUI_INNERDIALOG_TEXT 1019 $INSTDIR

  ; find and disable the directory selection box 
  ; We do not want users to type in this box
  FindWindow $R0 "#32770" "" $HWNDPARENT
  GetDlgItem $R1 $R0 1019 ;Text Box
  EnableWindow $R1 0

FunctionEnd

Примечание: я могу заставить работать кнопку обзора для одной из страниц каталога, но тогда, когда я на второй странице, автоматически заполняется фактическое, автоматически заполняется неправильно

Ответы [ 2 ]

4 голосов
/ 06 января 2012

Имя добавляемой папки является постоянным и задается во время компиляции, с этим связан отчет об ошибке .

Мой совет - отказаться от функции добавления и предоставить пользователю полный доступ.контроль над двумя пунктами назначения:

Name "NSIS Test"
InstallDir ""
!include MUI.nsh
Var DirClient
Var DirServer

Function .onInit
;Set default destinations
StrCpy $DirClient "$ProgramFiles\$(^Name)\Client"
StrCpy $DirServer "$ProgramFiles\$(^Name)\Server"
FunctionEnd

!macro ConfigureMyDirPage type var
!define MUI_DIRECTORYPAGE_VARIABLE ${var}
!define MUI_PAGE_HEADER_SUBTEXT "Choose the folder in which to install $(^NameDA) ${type}"
!define MUI_DIRECTORYPAGE_TEXT_TOP "Setup will install $(^NameDA) ${type} in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK"
!define MUI_DIRECTORYPAGE_TEXT_DESTINATION "${type} $(^DirSubText)"
!macroend

!insertmacro ConfigureMyDirPage "Client" $DirClient
!insertmacro MUI_PAGE_DIRECTORY

!insertmacro ConfigureMyDirPage "Server" $DirServer
!insertmacro MUI_PAGE_DIRECTORY

!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_LANGUAGE "English"

Section
DetailPrint DirClient=$DirClient
DetailPrint DirServer=$DirServer
SectionEnd
4 голосов
/ 06 января 2012

Хорошо, я наконец понял это.В основном есть функция, которая вызывается для «проверки» пути после нажатия кнопки обзора.Я привязал к этой функции и добавил руководство к каталогу, если это необходимо.Для этого я создал новую переменную и установил ее в функцию, вызываемую при отображении страницы, следующим образом:

; Client Directory
!define MUI_PAGE_CUSTOMFUNCTION_SHOW ShowPageClient
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ClientDirectoryLeave
!insertmacro MUI_PAGE_DIRECTORY

; Setup the page display for the client install page
Function ShowPageClient
  ; setup intal directory
  Push $0
  StrCpy $0 $PROGRAMFILES 2 #
  StrCpy $INSTDIR "$0\${CLIENT_FOLDER_NAME}"
  Pop $0

  !insertmacro MUI_INNERDIALOG_TEXT 1019 $INSTDIR

  FindWindow $R0 "#32770" "" $HWNDPARENT
  GetDlgItem $R1 $R0 1019 ;Text Box
  EnableWindow $R1 0

  ; Setup the client or server variable to indicate that
  ; we're in the client install part to signal the .onVerifyInstDir function
  ; to put the correct directory
  StrCpy $CLIENT_OR_SERVER "client"
FunctionEnd

Функция, которая вызывается после просмотра, имеет вид .onVerifyInstDir, поэтому я проверяю CLIENT_OR_SERVERпеременной и задайте путь соответствующим образом

; This function is special and is called any time a
; path is validated on returning from the browse button
; need to append the correct directory if it does not already exists
; in the install directory path
Function .onVerifyInstDir
  ; save the current $0 register, as it is used in this function
  Push $0

  ${If} $CLIENT_OR_SERVER == "client"
    ; in the client stage so directory must contain CLIENT_FOLDER_NAME
    ${StrContains} $0 "${CLIENT_FOLDER_NAME}" "$INSTDIR"
    ${If} $0 == ""
      ; the install dir does not contain the folder so append it
      StrCpy $INSTDIR "$INSTDIR\${CLIENT_FOLDER_NAME}"
    ${EndIf}
  ${Else}
    ; in the server stage so directory must contain SERVER_FOLDER_NAME
    ${StrContains} $0 "${SERVER_FOLDER_NAME}" "$INSTDIR"
    ${If} $0 == ""
      ; the install dir does not contain the folder so append it
      StrCpy $INSTDIR "$INSTDIR\${SERVER_FOLDER_NAME}"
    ${EndIf}
  ${EndIf}

  ; pop the saved register value
  Pop $0
FunctionEnd

Пара замечаний: использованная мной функция StrContains была найдена здесь: http://nsis.sourceforge.net/StrContains

Дополнительную ссылку на функцию .onVerifyInstDir можно найти здесь: http://nsis.sourceforge.net/Docs/Chapter4.html#4.7.2.1.10

...