PDA

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


Страниц : 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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

silione
27-01-2011, 02:23
Такая ситуация:
Есть два компонента которые нельзя устанавливать одновременно (как это осуществить с помощью радиобутонов я знаю), но так же нужно сделать так, чтобы оба компонента можно было не устанавливать.

Как я понял, радиобутонами такое сделать можно, если просто добавить "пустой" третий компонент, при выборе которого не будет, соответственно, устанавливаться ни один из первых двух. Считаю такое решение не очень красивым.

Слышал что можно сделать выбор с помощью обычных чекбоксов, на вроде проверки. Если стоит галочка 1, то галочка 2 убирается и наоборот, если стоит галочка 2, то галочка 1 убирается. При этом галочку можно убрать совсем ,и ни один из двух компонентов выбран не будет. Но никак не соображу как такое реализовать.

Подскажите пожалуйста, лучше с примером сразу.

kotkovets
27-01-2011, 12:30
Слышал что можно сделать выбор с помощью обычных чекбоксов, на вроде проверки. »
Можно сделать и так, но нужно делать промежуточное состояние секций.
Т.е выбор нужной секции - двойным нажатием.
!include "MUI2.nsh"
!include "Sections.nsh"

!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"
OutFile "File.exe"

SectionGroup /e "Компоненты" IDG

Section "Компонент №1" ID_1
SectionEnd

Section /o "Компонент №2" ID_2
SectionEnd

SectionGroupEnd

Function .onInit
StrCpy $1 ${ID_1}
FunctionEnd

Function .onSelChange
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${ID_1}
!insertmacro RadioButton ${ID_2}
SectionSetFlags ${IDG} ${SECTION_OFF}
!insertmacro EndRadioButtons
FunctionEnd

silione
03-02-2011, 14:36
Всплыла другая проблема.
Если имеются несколько групп секций и в какой-либо функции используется

SectionSetFlags ${IDG} ${SECTION_OFF}

с групп секций (всех) перестают сбрасываться флажки.

Например, если секции в группах относятся к разным InstType и при одном из вариантов должны отключаться все секции в одной из групп, то секции-то отключаются, а вот флажок на самой группе - нет (отключается только если по нему вручную щелкнуть).

Можно ли это как-то исправить?


!include "MUI2.nsh"
!include "Sections.nsh"

!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"

InstType "все"
InstType "один"

OutFile "File.exe"

Section "Компонент №0" ID_0
SectionIn 1 2
SectionEnd

SectionGroup /e "Компоненты" IDG

Section "Компонент №1" ID_1
SectionIn 1
SectionEnd

Section /o "Компонент №2" ID_2
SectionEnd

SectionGroupEnd

SectionGroup /e "Компоненты 2" IDG2

Section "Компонент №3" ID_3
SectionIn 1
SectionEnd

Section /o "Компонент №4" ID_4
SectionIn 1
SectionEnd

SectionGroupEnd

Function .onInit
StrCpy $1 ${ID_1}
FunctionEnd

Function .onSelChange
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${ID_1}
!insertmacro RadioButton ${ID_2}
SectionSetFlags ${IDG} ${SECTION_OFF}
!insertmacro EndRadioButtons
FunctionEnd

kotkovets
03-02-2011, 17:45
silione,
Ну здесь, уже не прокатит трюк фиктивного отключения группы - в наличие неопределенные состояния групп, отсюда и глюки.
1. Нужно определить начальное состояние секций и групп.
2. Разработать логику переключения и рулить флагами секций.
И дальше "прыгать" по логическим меткам (Это вечная проблема с секциями в NSIS).
!include "MUI2.nsh"
!include "Sections.nsh"

!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"

InstType "все"
InstType "один"

OutFile "File.exe"

Section "Компонент №0" ID_0
SectionIn 1 2
SectionEnd

SectionGroup /e "Компоненты" IDG

Section "Компонент №1" ID_1
SectionIn 1
SectionEnd

Section /o "Компонент №2" ID_2
SectionEnd

SectionGroupEnd

SectionGroup /e "Компоненты 2" IDG2

Section "Компонент №3" ID_3
SectionIn 1
SectionEnd

Section /o "Компонент №4" ID_4
SectionIn 1
SectionEnd

SectionGroupEnd

Function .onInit
Push $0
StrCpy $R0 ${ID_1}
SectionGetFlags ${ID_1} $0
IntOp $0 $0 | ${SF_SELECTED}
SectionSetFlags ${ID_1} $0
SectionGetFlags ${ID_2} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_2} $0
Pop $0
FunctionEnd

Function .onSelChange
Push $0
StrCmp $R0 ${ID_1} Check_ID_1
SectionGetFlags ${ID_1} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Done Done
StrCpy $R0 ${ID_1}
SectionGetFlags ${ID_2} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_2} $0
Goto Done
Check_ID_1:
SectionGetFlags ${ID_2} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Done Done
StrCpy $R0 ${ID_2}
SectionGetFlags ${ID_1} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_1} $0
Done:
Pop $0
FunctionEnd

shell7777
04-02-2011, 17:34
Есть ; one-section.nsi
;
; This example demonstrates how to control section selection.
; It allows only one of the sections of a group to be selected.

;--------------------------------

; Section define/macro header file
; See this header file for more info

!include "Sections.nsh"

;--------------------------------

Name "One Section"
OutFile "one-section.exe"
RequestExecutionLevel user

;--------------------------------

; Pages

Page components

;--------------------------------

; Sections


SectionGroup /e "GROUP" www

Section "Group 1 - Option 1" g1o1
SectionEnd

Section /o "Group 1 - Option 2" g1o2
SectionEnd

Section /o "Group 1 - Option 3" g1o3
SectionEnd

Section "Group 2 - Option 1" g2o1
SectionEnd

Section /o "Group 2 - Option 2" g2o2
SectionEnd

Section /o "Group 2 - Option 3" g2o3
SectionEnd
SectionGroupEnd
;--------------------------------

; Functions

; $1 stores the status of group 1
; $2 stores the status of group 2

Function .onInit

StrCpy $1 ${g1o1} ; Group 1 - Option 1 is selected by default
StrCpy $2 ${g2o1} ; Group 2 - Option 1 is selected by default

FunctionEnd

Function .onSelChange

!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${g1o1}
!insertmacro RadioButton ${g1o2}
!insertmacro RadioButton ${g1o3}
!insertmacro EndRadioButtons

!insertmacro StartRadioButtons $2
!insertmacro RadioButton ${g2o1}
!insertmacro RadioButton ${g2o2}
!insertmacro RadioButton ${g2o3}

!insertmacro EndRadioButtons

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

kotkovets
04-02-2011, 17:40
shell7777,
По этому поводу я уже отвечал здесь (http://forum.oszone.net/post-1566904-917.html)
Function .onInit
SectionSetFlags ${www} ${SECTION_OFF} #отключаем группу
SectionSetFlags ${g1o1} ${SF_SELECTED} #определяем, как отмеченный компонент
SectionSetFlags ${g2o1} ${SF_SELECTED} #определяем, как отмеченный компонент
StrCpy $1 ${g1o1} ; Group 1 - Option 1 is selected by default
StrCpy $2 ${g2o1} ; Group 2 - Option 1 is selected by default
FunctionEnd

shell7777
04-02-2011, 17:47
kotkovets,
огромнейшее приогромнейшее спасибо!!!!
Урааа....

silione
06-02-2011, 12:32
Я, видимо, дуб.
Почему у меня "компонент №3" может отмечаться одновременно с первым или вторым?
И как при всем этом сделать так, чтобы при нажатии на группу "компоненты 1" галочка, либо снималась совсем, либо происходил последовательный перебор между 1, 2 и 3 компонентой?

!include "MUI2.nsh"
!include "Sections.nsh"

!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"

InstType "все"
InstType "не все"

OutFile "File.exe"

Section "Компонент 0" ID_0
SectionIn 1 2
SectionEnd

SectionGroup /e "Компоненты 1" IDG1

Section /o "Компонент 1" ID_1
SectionIn 2
SectionEnd

Section "Компонент 2" ID_2
SectionIn 1
SectionEnd

Section /o "Компонент 3" ID_3
SectionEnd

SectionGroupEnd

SectionGroup /e "Компоненты 2" IDG2

Section "Компонент 4" ID_4
SectionIn 1
SectionEnd

Section "Компонент 5" ID_5
SectionIn 1
SectionEnd

SectionGroupEnd

Function .onInit
Push $0
StrCpy $R0 ${ID_2}
SectionGetFlags ${ID_1} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_1} $0
SectionGetFlags ${ID_2} $0
IntOp $0 $0 | ${SF_SELECTED}
SectionSetFlags ${ID_2} $0
SectionGetFlags ${ID_3} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_3} $0
Pop $0
FunctionEnd

Function .onSelChange
Push $0
StrCmp $R0 ${ID_1} Check_ID_1
SectionGetFlags ${ID_1} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Done Done
StrCpy $R0 ${ID_1}
SectionGetFlags ${ID_2} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_2} $0
SectionGetFlags ${ID_3} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_3} $0
Goto Done
Check_ID_1:
StrCmp $R0 ${ID_2} Check_ID_2
SectionGetFlags ${ID_2} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Done Done
StrCpy $R0 ${ID_2}
SectionGetFlags ${ID_1} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_1} $0
SectionGetFlags ${ID_3} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_3} $0
Check_ID_2:
SectionGetFlags ${ID_3} $0
IntOp $0 $0 & ${SF_SELECTED}
IntCmp $0 ${SF_SELECTED} 0 Done Done
StrCpy $R0 ${ID_3}
SectionGetFlags ${ID_1} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_1} $0
SectionGetFlags ${ID_2} $0
IntOp $0 $0 & ${SECTION_OFF}
SectionSetFlags ${ID_2} $0
Done:
Pop $0
FunctionEnd

kotkovets
06-02-2011, 14:54
silione,
Могу в этом случае (дабы не выносить мозг :) ) порекомендовать так:
http://forum.oszone.net/post-1326443-307.html

silione
06-02-2011, 20:35
Ыыыыыыыыыыыыы... Ну да, это работает, но сейчас задам самый тупой вопрос...
А как при всем этом сделать чтобы только один раз щелкать по строке?
У меня такое ощущение, что замкнутый круг получается, исправляя одну траблу, получаем другую...

kotkovets
07-02-2011, 00:05
А как при всем этом сделать чтобы только один раз щелкать по строке? »
Это вряд ли - ограничение NSIS, ведь когда отмечаешь чебокс группы, должны отмечатся чебоксы или снимается чебоксы в секционной группе, следовательно изменяются флаги секций с 0 на 1. И при отметке чебоксов секций флаги изменяются (с двух сторон палят пушками в секции :), куда им деваться то!). В последнем примере - именно так сделано на такой логике переключения секций, т.е при флаге равным 0 - секция не отмечена и наоборот.

ЗЫ. хотя явно утверждать не буду, что нельзя именно так и сделать переключения...Ведь я всего в NSIS не знаю:)

hb860
16-02-2011, 19:29
Где можно почитать про реализацию ключей при "тихой установке" которая используется тут? »
Я, как автор "ключей", готовлю техническую статью о том, как такое сделать, и в частности, как сделать генератор ответов для интсталлятора. Всё будет.

treylav
17-02-2011, 00:17
Столкнулся со следующей проблемой:
Для хранения пути к папке, из которой скрипт берёт файлы на упаковку, я использую переменную. Внутри этой переменной я успешно использую другие переменные, объявленные внутри скрипта, но не могу использовать переменные окружения (например, $PROGRAMFILES): компилятор не преобразует их в пути, а воспринимает как простой текст.
Пример участка кода:
!define PRODUCT_NAME "Mega_Project"
!define INSTALL_FILES_PATH "$PROGRAMFILES\${PRODUCT_NAME}"

Section "Install"
File /r "${INSTALL_FILES_PATH}\*.*"
SectionEnd
Реакция компилятора на подобный код:
File: Returning to: "$PROGRAMFILES\Mega_Project"
File: "$PROGRAMFILES\Mega_Project\*.*" -> no files found.
Usage: File [/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |
/oname=outfile one_file_only)
Вопрос: NSIS просто не позволяет делать такие финты или хромает моя реализация?
Спасибо.

kotkovets
17-02-2011, 01:39
хромает ... реализация »
И полное отсутствие чтения справки и просмотров примеров в папке NSIS...
!define - вообще то, эта команда препроцессора NSIS - помещает опр. значение в константу INSTALL_FILES_PATH (в вашем примере). А константа означает - постоянное, неизменное значение. А вы же пытаетесь, предопределенную переменную $PROGRAMFILES засунуть в константу, а на этапе компиляции эта переменная еще не определена !
Читайте справку по NSIS ! и почитайте Справочник по NSIS (http://forum.oszone.net/post-1569008-918.html)
А делать нужно так:

!define INSTALL_FILES_PATH "C:\Program files\Proga"
!define PRODUCT_NAME "Mega_Project"
InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"

Section "Install"
SetOutPath "$INSTDIR"
File /r "${INSTALL_FILES_PATH}\*.*"
SectionEnd
Причем пути для забора файлов в инсталлятор прописываются только абсолютные или относительно компилируемого скрипта или компилятора NSIS

BSL
20-02-2011, 19:01
Добрый вечер, только начал изучать NSIS.

Есть проблемка. Во время установки если пользователь выбирает определенную Section скажем установка «Сервера приложений», то перед установкой необходимо дополнительно запросить к примеру порт. То есть как я понимаю перед установкой должно появиться окно с параметром. Как этого добиться?

kotkovets
20-02-2011, 21:05
необходимо дополнительно запросить к примеру порт. То есть как я понимаю перед установкой должно появиться окно с параметром. Как этого добиться? »
Если Вы так хотите сделать, то нужно делать:
1) проверить, отмечена ли нужная секция
2) Если отмечена секция вызывать соответствующий диалог и вызывать при закрытии стр. выбора компонентов.
Самый простой пример, это с использованием плагина DialogsEx (http://winxpregp.narod.ru/mfiles/NSIS/dialogsex.zip)
файлик DialogsEx.dll закидываем в C:\Program Files\NSIS\Plugins
и хедер dialogs.nsh закидываем в C:\Program Files\NSIS\Include
!include "MUI2.nsh"
!include "dialogs.nsh"

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE COMPONENTSLEAVE ; функция будет выполнена при закрытии стр. компонентов.
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "Russian"

ShowInstDetails show
InstallDir "$EXEDIR"
OutFile Test.exe
Caption "Test"

Section "Port" SecPort
MessageBox MB_OK "Номер выбраннога порта: $0" ;показываю в качестве примера значение $0
SectionEnd

Function COMPONENTSLEAVE
${If} ${SectionIsSelected} SecPort ;проверка выбрана ли нужная секция
${InputTextBox} "Окно выбора номера порта" "Введите номер порта в поле ввода..." "" "4" "" "" 0
;число 0 - в переменной $0 будет хранится введеное значение порта
;число 4 - соответствует максимально возможному количеству вводимых символов
StrCmp $0 `` 0 +2 ;если в переменной $0 пустое значение возврат на стр. выбора компонентов
Abort
${EndIf}
FunctionEnd

BSL
21-02-2011, 09:43
kotkovets спасибо, большое. Предложенный вариант работает, и для меня это выход.
Но возник дополнительный вопрос.
Возможно ли сделать так что после выбора компонентов, и нажатие кнопки "Далее", возникало не отдельное окно с контролом порт, а была бы следующая страница с контролом порт, А после этого уже установка.

hb860
21-02-2011, 10:43
BSL, вы можете "нарисовать" свою собственную страницу. Это очень просто. Посмотрите этот пример (http://winreview.ru/NSIS/241/Sozdanie-svoego-installyatora-na-NSIS-Sozdaem-sobstvennie-stranitci-installyatora). Как я понял, вам нужно будет создать только одно текстовое поле и одну надпись.

BSL
21-02-2011, 11:08
hb860, и изучал эту ссылку. Загвоздка в том я смогу создать свою страницу, но как научить ее отображать её или нет в зависимости от выбранной секции.

kotkovets
21-02-2011, 12:57
Загвоздка в том я смогу создать свою страницу, но как научить ее отображать её или нет в зависимости от выбранной секции »
Делается точно также, но с небольшой "модификацией". Нечто подобное делал для себя, вот кусок скрипта:
!include "MUI2.nsh"
!include "dialogs.nsh"

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!define MUI_PAGE_CUSTOMFUNCTION_SHOW COMPONENTSSHOW
!insertmacro MUI_PAGE_COMPONENTS
Page custom PortShow PortLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "Russian"

ShowInstDetails show
InstallDir "$EXEDIR"
OutFile Test.exe
Caption "Test"

Var Dialog
Var Label
Var Number
Var Port

Section /o "Port" SecPort
MessageBox MB_OK "Номер выбраннога порта: $Port" ;показываю в качестве примера значение $0
SectionEnd

Function COMPONENTSSHOW ;функция при открытии стр. компонентов
${If} ${SectionIsSelected} SecPort ;если выбрана секция
GetDlgItem $0 $HWNDPARENT 1
${NSD_SetText} $0 `$(^NextBtn)` ;переименовываем кнопку
${ElseIfNot} ${SectionIsSelected} SecPort ;если не выбрана секция
GetDlgItem $0 $HWNDPARENT 1
${NSD_SetText} $0 `$(^InstallBtn)` ;переименовываем кнопку
${EndIf}
FunctionEnd

Function .onSelChange
${If} ${SectionIsSelected} SecPort ;если выбрана секция
GetDlgItem $0 $HWNDPARENT 1
${NSD_SetText} $0 `$(^NextBtn)` ;переименовываем кнопку
${ElseIfNot} ${SectionIsSelected} SecPort ;если не выбрана секция
GetDlgItem $0 $HWNDPARENT 1
${NSD_SetText} $0 `$(^InstallBtn)` ;переименовываем кнопку
${EndIf}
FunctionEnd

Function PortShow
${If} ${SectionIsSelected} SecPort ;проверка выбрана ли нужная секция
nsDialogs::Create 1018
Pop $Dialog
${NSD_CreateLabel} 0 0u 130u 13u "Введите в поле ввода номер порта:"
Pop $Label
${NSD_CreateNumber} 0 13u 40% 13u "" ;ввод только цифры
Pop $Number
${NSD_SetTextLimit} $Number 4 ;лимит на 4 символа
nsDialogs::Show
${EndIf}
FunctionEnd

Function PortLeave
${NSD_GetText} $Number $Port ;считываем текст контрола
StrLen $2 $Port ;считываем количество введенных символов с $Port в $2
IntCmp $2 4 +2 0 0 ;если меньше или больше 4 символов - возврат назад
Abort
FunctionEnd

И обязательно все функции, которые работают с секциями, размещать в скрипте после всех секций - для корректного считывания индетификаторов секций.




© OSzone.net 2001-2012