Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
AlekseyPopovv
01-10-2019, 11:28
iglezz,
Ага, въехал...
А как сделать что бы инсталлятор нельзя было открыть в 7z?
Можно в личку.
AlekseyPopovv
04-10-2019, 17:59
Как создать MUI_PAGE_DIRECTORY custom?
И как задать разные InstallDir для обычной и портативной версий?
Как создать MUI_PAGE_DIRECTORY custom? »
Справочник по NSIS (http://forum.oszone.net/thread-168287.html) => Описания плагинов => nsDialogs: Создаем собственные страницы инсталлятора
И как задать разные InstallDir для обычной и портативной версий? »
InstallDir можно переназначить в любой момент назначением переменной $INSTDIR путь нужного каталога, меняйте значение этой переменной в том участке кода, где пользователь делает выбор: обычная или портативная
AlekseyPopovv
04-10-2019, 18:42
в любой момент назначением переменной $INSTDIR »
А как быть с выбором папки на MUI_PAGE_DIRECTORY? По умолчанию обычная и портативная предлагают установку в $PROGRAMFILES\${APP} (InstallDir "$PROGRAMFILES\${APP}"), а хотелось бы портативную в $EXEDIR\${APP} Portable.
А как быть с выбором папки на MUI_PAGE_DIRECTORY? По умолчанию обычная и портативная предлагают установку в $PROGRAMFILES\${APP} (InstallDir "$PROGRAMFILES\${APP}"), а хотелось бы портативную в $EXEDIR\${APP} Portable. »
Так вы дайте больше инфы или кусок своего кода, чтобы мы конкретно подсказали, какие команды вам использовать в коде или, может, сами пример накидаем, сейчас мы в угадайку будем так играть с вами, я же не знаю, как вы пользователю предлагаете сделать выбор:
1) Показать диалог с взаимоисключаемыми секциями
2) На собственной созданной страничке поставили 2 радиобаттона и юзер жмакает тот, который ему нужен (обычная/портативная установки)
3) Или тупо при заапуске показываете мессадж-бокс (сообщение с вопросом "Портативку не желаете?")... :)
4) Если собственная страничка, то чем создаёте? InstallOptions или nsDialogs?
вот как-то так...Ребята, задавайте более конкретные вопросы или сразу кидайте свой код, задаёте размытые вопросы - размытые ответы и получаете...
небольшой пример со стандартными средствами с взаимоисключаемыми компонентами (некрасиво, старо и не модно, мне лень что-то воротить "впустую") :)
!include "MUI.nsh"
!include "Sections.nsh"
!include "Logiclib.nsh"
!define MUI_COMPONENTSPAGE_SMALLDESC
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
Page custom PageCreate
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "Russian"
Name "TESTttt"
OutFile "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.exe"
InstallDir "$TEMP"
ShowInstDetails nevershow
Section "Обычная установка" ID_1
SectionEnd
Section /o "Портативная" ID_2
SectionEnd
Function .onSelChange
; Выбор между компонентам 1, 2
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${ID_1}
!insertmacro RadioButton ${ID_2}
!insertmacro EndRadioButtons
FunctionEnd
Function .onInit
StrCpy $1 ${ID_1}
FunctionEnd
Function PageCreate
SectionGetFlags ${ID_1} $0 ; Получаем флаги секции
IntOp $0 $0 & ${SF_SELECTED} ; Проверяем, отмеченая ли для установки секция "Обычная установка"
${If} $0 == 1 ; Если $0 = 1, значит секция отмечена для установки
StrCpy $INSTDIR "$PROGRAMFILES\TEST"
${Else}
StrCpy $INSTDIR "$EXEDIR\TEST"
${EndIf}
FunctionEnd
Section -Post
SectionEnd
AlekseyPopovv
05-10-2019, 06:18
Так вы дайте больше инфы или кусок своего кода »
!include "MUI2.nsh"
Page Custom FnCustPage FnRadioCheck
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"
Name "Test"
InstallDir "$TEMP"
OutFile "Test.exe"
ShowInstDetails nevershow
Var Dialog
Var Check
Var Check1
Var CheckBox
Var CheckBox1
Var Radio
Var Radio1
Var RadioButton
Var RadioButton1
Function FnCustPage
nsDialogs::Create 1018
Pop $Dialog
${NSD_CreateRadioButton} 5u 10u 124u 12u "1"
Pop $RadioButton
${NSD_SetState} $RadioButton 1
${NSD_OnClick} $RadioButton RadioButton
${NSD_CreateRadioButton} 5u 22u 124u 12u "1"
Pop $RadioButton1
${NSD_OnClick} $RadioButton1 RadioButton1
${NSD_CreateCheckBox} 5u 60u 124u 12u "2"
Pop $CheckBox
${NSD_SetState} $CheckBox 1
${NSD_CreateCheckBox} 5u 72u 124u 12u "2"
Pop $CheckBox1
${NSD_SetState} $CheckBox1 1
nsDialogs::Show
FunctionEnd
Function Switching
${NSD_GetState} $RadioButton $Radio
${If} $Radio == 1
EnableWindow $CheckBox 1
EnableWindow $CheckBox1 1
${NSD_SetState} $CheckBox 1
${NSD_SetState} $CheckBox1 1
${Else}
EnableWindow $CheckBox 0
EnableWindow $CheckBox1 0
${NSD_SetState} $CheckBox 0
${NSD_SetState} $CheckBox1 0
${EndIf}
FunctionEnd
Function RadioButton
Pop $RadioButton
Call Switching
FunctionEnd
Function RadioButton1
Pop $RadioButton1
Call Switching
FunctionEnd
Function FnRadioCheck
${NSD_GetState} $RadioButton $Radio
${NSD_GetState} $RadioButton1 $Radio1
${NSD_GetState} $CheckBox $Check
${NSD_GetState} $CheckBox1 $Check1
FunctionEnd
Section
${If} $Radio == 1
DetailPrint ""
StrCpy $INSTDIR "$PROGRAMFILES\Install"
${EndIf}
SectionEnd
Section
${If} $Radio1 == 1
DetailPrint ""
StrCpy $INSTDIR "$EXEDIR\Portable"
${EndIf}
SectionEnd
Section
${If} $Check == 1
DetailPrint ""
${EndIf}
${If} $Check1 == 1
DetailPrint ""
${EndIf}
SectionEnd
Чего не хватает?
AlekseyPopovv, отвечу сразу на вопрос, заданный в личке
При нажатии кнопки "Назад" - у вас диалог заново инициализируется с вашими прописанными состояниями элементов
Соответственно, чтобы сделать более умный диалог, нам нужно код написать таким образом, чтобы он учитывал сей факт, что кто-то нажмёт "Назад" и нам будет необходимо поставить всё так, как выставил пользователь
Для этого, нам нужно сначала в секцию .onInit прописать в переменные, состояние элементов управления по-умолчанию:
Function .onInit
StrCpy $Radio 1
StrCpy $Radio1 0
StrCpy $Check 1
StrCpy $Check1 1
FunctionEnd
Затем заменим ваш кусок кода:
Function FnCustPage
nsDialogs::Create 1018
Pop $Dialog
${NSD_CreateRadioButton} 5u 10u 124u 12u "1"
Pop $RadioButton
${NSD_SetState} $RadioButton 1
${NSD_OnClick} $RadioButton RadioButton
${NSD_CreateRadioButton} 5u 22u 124u 12u "1"
Pop $RadioButton1
${NSD_OnClick} $RadioButton1 RadioButton1
${NSD_CreateCheckBox} 5u 60u 124u 12u "2"
Pop $CheckBox
${NSD_SetState} $CheckBox 1
${NSD_CreateCheckBox} 5u 72u 124u 12u "2"
Pop $CheckBox1
${NSD_SetState} $CheckBox1 1
nsDialogs::Show
FunctionEnd
Этим:
Function FnCustPage
nsDialogs::Create 1018
Pop $Dialog
${NSD_CreateRadioButton} 5u 10u 124u 12u "1"
Pop $RadioButton
${NSD_SetState} $RadioButton $Radio ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
${NSD_OnClick} $RadioButton RadioButton
${NSD_CreateRadioButton} 5u 22u 124u 12u "1"
Pop $RadioButton1
${NSD_SetState} $RadioButton1 $Radio1 ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
${NSD_OnClick} $RadioButton1 RadioButton1
${NSD_CreateCheckBox} 5u 60u 124u 12u "2"
Pop $CheckBox
${NSD_SetState} $CheckBox $Check ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
${NSD_CreateCheckBox} 5u 72u 124u 12u "2"
Pop $CheckBox1
${NSD_SetState} $CheckBox1 $Check1 ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
EnableWindow $CheckBox $Radio ; Активируем/деактивируем чекбокс из значения радиобаттона
EnableWindow $CheckBox1 $Radio ; Активируем/деактивируем чекбокс1 исходя из значения радиобаттона
nsDialogs::Show
FunctionEnd
Этим мы делаем нашу функцию "умной" с возможностью подхватывать те значения, которые пользователь выбрал и, если вдруг, решил вернуться на страничку
Далее заменим
Function Switching
${NSD_GetState} $RadioButton $Radio
${If} $Radio == 1
EnableWindow $CheckBox 1
EnableWindow $CheckBox1 1
${NSD_SetState} $CheckBox 1
${NSD_SetState} $CheckBox1 1
${Else}
EnableWindow $CheckBox 0
EnableWindow $CheckBox1 0
${NSD_SetState} $CheckBox 0
${NSD_SetState} $CheckBox1 0
${EndIf}
FunctionEnd
на
Function Switching
${NSD_GetState} $RadioButton $Radio ; Получаем статус радиобаттона
EnableWindow $CheckBox $Radio ; и используем это значение для активации/деактивации элементов
EnableWindow $CheckBox1 $Radio ; и используем это значение для активации/деактивации элементов
${NSD_SetState} $CheckBox $Radio ; и используем это значение для назначения статуса чекбоксу
${NSD_SetState} $CheckBox1 $Radio ; и используем это значение для назначения статуса чекбоксу
FunctionEnd
так мы сделаем код более компактным, функционал остаётся тот же ;)
Теперь о том, чего не хватает
У вас переназначение $INSTDIR прописано в секции, это неправильно, т.к. секции обрабатываются непосредственно при начале установки в
!insertmacro MUI_PAGE_INSTFILES
соответственно, нам нужно переназначать $INSTDIR до появления диалога выбора директории установки
!insertmacro MUI_PAGE_DIRECTORY
Поэтому можно просто в конец функции FnCustPage прописать то, что нам нужно:
${If} $Radio == 1
StrCpy $INSTDIR "$PROGRAMFILES\Install"
DetailPrint "Папка установки: $INSTDIR"
${Else}
StrCpy $INSTDIR "$EXEDIR\Portable"
DetailPrint "Папка установки: $INSTDIR"
${EndIf}
Не обязательно проверять статус двух взаимоисключающих радиобаттанов, как это у вас прописано:
Section
${If} $Radio == 1
DetailPrint ""
StrCpy $INSTDIR "$PROGRAMFILES\Install"
${EndIf}
SectionEnd
Section
${If} $Radio1 == 1
DetailPrint ""
StrCpy $INSTDIR "$EXEDIR\Portable"
${EndIf}
SectionEnd
Можно сделать проверку по одному, ведь если логически подумать, то если первый радиобаттон не выбран - то выбран второй (при условии, опять же повторюсь, что они взаимоисключающие)
Но это чисто мой стиль написания, я не навязываю вам писать свой код таким же образом, просто так он будет выглядеть менее громоздким...
!include "MUI2.nsh"
Page Custom FnCustPage FnRadioCheck
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"
Name "Test"
InstallDir "$TEMP"
OutFile "Test.exe"
ShowInstDetails nevershow
Var Dialog
Var Check
Var Check1
Var CheckBox
Var CheckBox1
Var Radio
Var Radio1
Var RadioButton
Var RadioButton1
Function .onInit
StrCpy $Radio 1
StrCpy $Radio1 0
StrCpy $Check 1
StrCpy $Check1 1
FunctionEnd
Function FnCustPage
nsDialogs::Create 1018
Pop $Dialog
${NSD_CreateRadioButton} 5u 10u 124u 12u "1"
Pop $RadioButton
${NSD_SetState} $RadioButton $Radio ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
${NSD_OnClick} $RadioButton RadioButton
${NSD_CreateRadioButton} 5u 22u 124u 12u "1"
Pop $RadioButton1
${NSD_SetState} $RadioButton1 $Radio1 ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
${NSD_OnClick} $RadioButton1 RadioButton1
${NSD_CreateCheckBox} 5u 60u 124u 12u "2"
Pop $CheckBox
${NSD_SetState} $CheckBox $Check ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
${NSD_CreateCheckBox} 5u 72u 124u 12u "2"
Pop $CheckBox1
${NSD_SetState} $CheckBox1 $Check1 ; Используем переменные в значении статуса элемента (отмечен/не отмечен). Начальный статус элемента мы назначили в .onInit
EnableWindow $CheckBox $Radio ; Активируем/деактивируем чекбокс из значения радиобаттона
EnableWindow $CheckBox1 $Radio ; Активируем/деактивируем чекбокс1 исходя из значения радиобаттона
nsDialogs::Show
${If} $Radio == 1
StrCpy $INSTDIR "$PROGRAMFILES\Install"
DetailPrint "Папка установки: $INSTDIR"
${Else}
StrCpy $INSTDIR "$EXEDIR\Portable"
DetailPrint "Папка установки: $INSTDIR"
${EndIf}
FunctionEnd
Function Switching
${NSD_GetState} $RadioButton $Radio ; Получаем статус радиобаттона
EnableWindow $CheckBox $Radio ; и используем это значение для активации/деактивации элементов
EnableWindow $CheckBox1 $Radio ; и используем это значение для активации/деактивации элементов
${NSD_SetState} $CheckBox $Radio ; и используем это значение для назначения статуса чекбоксу
${NSD_SetState} $CheckBox1 $Radio ; и используем это значение для назначения статуса чекбоксу
FunctionEnd
Function RadioButton
Pop $RadioButton
Call Switching
FunctionEnd
Function RadioButton1
Pop $RadioButton1
Call Switching
FunctionEnd
Function FnRadioCheck
${NSD_GetState} $RadioButton $Radio
${NSD_GetState} $RadioButton1 $Radio1
${NSD_GetState} $CheckBox $Check
${NSD_GetState} $CheckBox1 $Check1
FunctionEnd
Section
${If} $Check == 1
DetailPrint ""
${EndIf}
${If} $Check1 == 1
DetailPrint ""
${EndIf}
SectionEnd
AlekseyPopovv
05-10-2019, 11:29
K.A.V., Как добавить картинки .bmp на каждый буттон?
${NSD_CreateBitmap} 150u 3u 100% 100% ""
Pop $Image
${NSD_SetImage} $Image "$PLUGINSDIR\1.bmp" $ImageHandle
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
AlekseyPopovv, если вы именно про то, чтобы заменить стиль квадратика галочки - то я не знаю, возможно, это делается только рисованием элемента "вручную" через стиль BS_OWNERDRAW
Может здесь кто таким вопросом озадачивался, подскажет
AlekseyPopovv
06-10-2019, 08:25
K.A.V., нет, я про картинки которые меняются при выборе "Установка" или "Распаковка".
Как здесь (http://forum.oszone.net/post-1817548.html#post1817548)
AlekseyPopovv, перед:
nsDialogs::Show
добавьте
${NSD_CreateBitmap} 150u 3u 100% 100% ""
Pop $Image
call SwitchImage
и в функцию Switching добавьте:
Function Switching
${NSD_GetState} $RadioButton $Radio ; Получаем статус радиобаттона
EnableWindow $CheckBox $Radio ; и используем это значение для активации/деактивации элементов
EnableWindow $CheckBox1 $Radio ; и используем это значение для активации/деактивации элементов
${NSD_SetState} $CheckBox $Radio ; и используем это значение для назначения статуса чекбоксу
${NSD_SetState} $CheckBox1 $Radio ; и используем это значение для назначения статуса чекбоксу
call FnRadioCheck
call SwitchImage ; вызов функции по смене изображения в зависимости от установки
FunctionEnd
и саму функцию по смене изображения добавьте:
Function SwitchImage
${If} $Radio == 1
${NSD_SetImage} $Image "ПУТЬ_К_ФАЙЛУ_ОБЫЧНАЯ_УСТАНОВКА\1.bmp" $ImageHandle
${Else}
${NSD_SetImage} $Image "ПУТЬ_К_ФАЙЛУ_ПОРТАТИВНАЯ_УСТАНОВКА\2.bmp" $ImageHandle
${EndIf}
FunctionEnd
AlekseyPopovv
06-10-2019, 09:59
K.A.V., Как пропустить (не показывать) страницу, если нет определённого параметра? И как назад?
Сделал так: :lamer:
StrCmp $R0 0 0 +50
K.A.V., Как пропустить (не показывать) страницу, если нет определённого параметра? И как назад?
Сделал так:
Код: Выделить весь код
StrCmp $R0 0 0 +50 »
:o
раз уж решились кодить на NSIS, почитайте тогда, как минимум, наш Справочник по NSIS (http://forum.oszone.net/thread-168287.html), в разделе "Статьи" для начала откройте для себя "метки", прочитав страничку "Labels: Метки, безусловные переходы", чтобы как минимум такой кошмар в коде не делать:
StrCmp $R0 0 0 +50 »
потом забудете про это "+50" и будете голову ломать, почему у вас скрипт не работает после каких-то доработок
Как пропустить (не показывать) страницу, если нет определённого параметра? И как назад »
Читать справку 4.5.3 Callbacks (https://nsis.sourceforge.io/Docs/Chapter4.html#pagecallbacks_explain).
Name "CallbackExampleSkipPage"
OutFile "CallbackExampleSkipPage.exe"
ShowInstDetails show
AutoCloseWindow false
RequestExecutionLevel user
Page components
Page directory dirPagePre
Page instfiles
Section "Install"
DetailPrint "Doing some stuff..."
SectionEnd
Section /o "Skip Directory Page" secDir
SectionEnd
Function dirPagePre
SectionGetFlags ${secDir} $1
IntOp $1 $1 << 7
StrCmp $1 128 0 +2
Abort
FunctionEnd
AlekseyPopovv
06-10-2019, 11:23
K.A.V., Я уже давненько пишу на NSIS, но редко, в основном портативные версии. Там таких "запар" с созданием страниц и т.д. нет. Спасибо за помощь. :yahoo:
iglezz, Сейчас попробую, а то забыл уже сколько строк добавил, опять заново считать. :shocked:
AlekseyPopovv
06-10-2019, 16:51
Как на "UnInstallBtn" назначить функцию на кастомной странице? Пример бы какой ни будь.
У меня все кнопки делают одно и тоже действие почему то...
Как на "UnInstallBtn" назначить функцию на кастомной странице? Пример бы какой ни будь. »
А где код, в котором этот "UnInstallBtn"?
AlekseyPopovv
06-10-2019, 17:01
Так нет его, только это:
${NSD_SetText} $0 "$(^UnInstallBtn)"
Внимательное чтение ${NSISDIR}\Docs\nsDialogs\Readme.html подскажет верный ответ.
Что-то в духе ${NSD_OnClick} $0 ИмяФункции
AlekseyPopovv
10-10-2019, 06:07
Как сделать, что бы при выборе папки установки дописывалась папка приложения?
Пример: "C:\Program Files\Proga\", а не так "C:\Program Files".
Как удалить пустую папку при закрытии инсталлятора или при нажатии кнопки отмена?
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC