PDA

Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 [117] 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

AlekseyPopovv
01-10-2019, 11:28
iglezz,
Ага, въехал...

А как сделать что бы инсталлятор нельзя было открыть в 7z?
Можно в личку.

AlekseyPopovv
04-10-2019, 17:59
Как создать MUI_PAGE_DIRECTORY custom?
И как задать разные InstallDir для обычной и портативной версий?

K.A.V.
04-10-2019, 18:20
Как создать 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.

K.A.V.
04-10-2019, 19:33
А как быть с выбором папки на 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
Чего не хватает?

K.A.V.
05-10-2019, 08:31
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

K.A.V.
06-10-2019, 08:22
AlekseyPopovv, если вы именно про то, чтобы заменить стиль квадратика галочки - то я не знаю, возможно, это делается только рисованием элемента "вручную" через стиль BS_OWNERDRAW
Может здесь кто таким вопросом озадачивался, подскажет

AlekseyPopovv
06-10-2019, 08:25
K.A.V., нет, я про картинки которые меняются при выборе "Установка" или "Распаковка".
Как здесь (http://forum.oszone.net/post-1817548.html#post1817548)

K.A.V.
06-10-2019, 08:53
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.
06-10-2019, 11:12
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" и будете голову ломать, почему у вас скрипт не работает после каких-то доработок

iglezz
06-10-2019, 11:18
Как пропустить (не показывать) страницу, если нет определённого параметра? И как назад »
Читать справку 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" назначить функцию на кастомной странице? Пример бы какой ни будь.
У меня все кнопки делают одно и тоже действие почему то...

iglezz
06-10-2019, 16:59
Как на "UnInstallBtn" назначить функцию на кастомной странице? Пример бы какой ни будь. »
А где код, в котором этот "UnInstallBtn"?

AlekseyPopovv
06-10-2019, 17:01
Так нет его, только это:
${NSD_SetText} $0 "$(^UnInstallBtn)"

iglezz
06-10-2019, 17:10
Внимательное чтение ${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