Войти

Показать полную графическую версию : .: 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

iglezz
29-09-2023, 20:33
Пример бы посмотреть, самый простой. »
Код по ссылке компилируется и работает. С модификацией могут быть проблемы, но они решаемы.

Как считать путь к папке OCR? Пользователь может выбрать любое расположение папки. »
Считать откуда?

AlekseyPopovv
29-09-2023, 21:05
Считать откуда? »
С реестра. К примеру там будет такой путь:
WriteRegStr HKCU "${APPREG}\OCR" "LanguagesPath" "@ByteArray(D:/Programs/OCR)"
Как теперь его преобразовать в "D:\Programs\OCR"?

iglezz
29-09-2023, 22:23
AlekseyPopovv, Если формат строки известен и постоянен, то очевидно, что достаточно отрезать @ByteArray( в начале строки и ) в конце

AlekseyPopovv
30-09-2023, 21:14
Как преобразовать?
Это:
01-01-2023 00:00:00 RTZ 2 (ceia)
В это:
01-01-2023 00:00:00 RTZ 2
Мой код, но соответственно удаляется и RTZ. В скобках может быть любое слово маленькими буквами.
${StrFilter} "$1" "12" " -:" "()абвгдеёжзийклмнопрстуфхцчшщъыьэюяabcdefghijklmnopqrstuvwxyz" $0
А лучше вообще удалить всё что в скобках...

iglezz
30-09-2023, 22:21
Как преобразовать? »
Использовать ${StrLoc} для поиска позиции открывающей скобки и т.д.
StrCpy $0 '01-01-2023 00:00:00 RTZ 2 (ceia)'
StrCpy $1 ''
${StrLoc} $1 $0 '(' <
${If} $1 != ''
IntOp $1 $1 + 2
StrCpy $1 $0 -$1
${EndIf}
DetailPrint 'in [$0]'
DetailPrint 'out [$1]'

AlekseyPopovv
01-10-2023, 00:26
StrCpy $0 '01-01-2023 00:00:00 RTZ 2 (ceia)'
StrCpy $1 ''
${StrLoc} $1 $0 '(' <
${If} $1 != ''
IntOp $1 $1 + 2
StrCpy $1 $0 -$1
${EndIf}
DetailPrint 'in [$0]'
DetailPrint 'out [$1]' »
А как наоборот оставить только то что в скобках?

AlekseyPopovv
01-10-2023, 10:31
Как сменить имя и папку деинсталлятора, когда его запускаешь?
$TEMP\~nsu1.tmp\Un.exe
$TEMP\~nsu1.tmp
И если я просто его запускаю и отменяю удаление, то всё это остаётся в папке $TEMP. Как всё это удалить?

AlekseyPopovv
04-10-2023, 19:19
Как изменить размер окна инсталлятора на всех страницах без правки русурсов и плагина NsResize?

iglezz
06-10-2023, 01:12
Как сменить имя и папку деинсталлятора, когда его запускаешь? »
Никак.
Если сильно надо, сделать дополнительный скрипт, который будет служить в этой роли.
И если я просто его запускаю и отменяю удаление, то всё это остаётся в папке $TEMP. Как всё это удалить? »
В случае запуска с админскими привилегиями un.exe и каталог удаляются при перезагрузке.
Для простого юзера нужно колхозить подчистку.

Как изменить размер окна инсталлятора на всех страницах без правки русурсов и плагина NsResize? »
Зачем?

iglezz
06-10-2023, 02:37
Простейший способ подчистки за исполняемым файлом - запуск скрытого процесса перед завершением работы: :read: :read: :read: Бездумное применение нижеприведённого кода отстрелит ногу каталог с екзешником. SetAutoClose true
ExpandEnvStrings $0 '%COMSPEC%'
System::Call 'shell32::ShellExecute(pn,pn,tr0,ts,ts,i0)i' `/c timeout /t 3 & rd /s /q "$EXEDIR"` `$TEMP`

AlekseyPopovv
12-10-2023, 15:08
Как сохранить статус CheckBox на кастомных страницах?
К примеру снимаю галочку с CheckBox и возвращаюсь на предыдущую страницу, потом обратно на следующую и галочка опять стоит.

iglezz
13-10-2023, 22:57
Как сохранить статус CheckBox на кастомных страницах?
К примеру снимаю галочку с CheckBox и возвращаюсь на предыдущую страницу, потом обратно на следующую и галочка опять стоит. »
Завести под каждую галку переменную.
При создании страницы выставить статус галки из переменной.
При выходе со страницы (leave-функция и onBack-колбэк) записать статус галки в переменную.
ShowInstDetails show
RequestExecutionLevel user
InstallColors /windows
InstallDir $TEMP

Page components
page custom OptionsSaveLoadTest OptionsSaveLoadTest_Leave
Page directory
Page instfiles instfiles_pre

!include LogicLib.nsh
!include nsDialogs.nsh
!include Sections.nsh

Var Option1
Var Option2
Var hOption1
Var hOption2


Section
DetailPrint 'Exec mandatory section'
SectionEnd

Section /o '-Option 1' SecOpt1
DetailPrint 'Exec Option1 section'
SectionEnd

Section /o '-Option 2' SecOpt2
DetailPrint 'Exec Option2 section'
SectionEnd


Function OptionsSaveLoadTest
nsDialogs::Create 1018
Pop $0

GetFunctionAddress $0 OptionsSaveLoadTest_OnBack
nsDialogs::OnBack $0

${NSD_CreateCheckbox} 0 0 100% 8u 'Option&1'
Pop $hOption1
${IfThen} $Option1 == ${BST_CHECKED} ${|} ${NSD_Check} $hOption1 ${|}


${NSD_CreateCheckbox} 0 15u 100% 8u 'Option&2'
Pop $hOption2
${IfThen} $Option2 == ${BST_CHECKED} ${|} ${NSD_Check} $hOption2 ${|}

nsDialogs::Show
FunctionEnd

Function OptionsSaveLoadTest_OnBack
${NSD_GetState} $hOption1 $Option1
${NSD_GetState} $hOption2 $Option2
FunctionEnd

Function OptionsSaveLoadTest_Leave
Call OptionsSaveLoadTest_OnBack
FunctionEnd

Function instfiles_pre
${IfThen} $Option1 == ${BST_CHECKED} ${|} !insertmacro SelectSection ${SecOpt1} ${|}
${IfThen} $Option2 == ${BST_CHECKED} ${|} !insertmacro SelectSection ${SecOpt2} ${|}
FunctionEnd

Function .onInit
StrCpy $Option1 ${BST_UNCHECKED}
StrCpy $Option2 ${BST_UNCHECKED}
FunctionEnd

inco1
20-10-2023, 14:38
Всем хорошего дня.
Если на рабочем столе кликнуть правой кнопкой мыши, то там есть пункт "Обновить". Как эту команду прописать в NSIS?

iglezz
20-10-2023, 16:18
inco1, Можно программно нажать F5
System::Call 'user32::GetShellWindow()p.s' ; hwndShellWindow = GetShellWindow()
System::Call 'user32::SendMessage(ps,i0x111,i0x1A220,i0)' ; SendMessage(hwndShellWindow, WM_COMMAND, MAKELONG(KeyValue,1), NULL)

MKN
26-10-2023, 12:32
Подскажите пожалуйста, как средствами NSIS переконвертировать(сделать читабельной) последовательность символов (Unicode Escape), к примеру такого вида : \u0412\u0430\u043b\u0435\u043d\u0442\u0438\u043d ?

AlekseyPopovv
26-10-2023, 18:50
Как победить подобную конструкцию?
!macro Test
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\1" "Name"
StrCmp $0 "My" YESREG 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\2" "Name"
StrCmp $0 "My" YESREG 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\3" "Name"
StrCmp $0 "My" YESREG 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\4" "Name"
StrCmp $0 "My" YESREG 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\5" "Name"
StrCmp $0 "My" YESREG 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\6" "Name"
StrCmp $0 "My" YESREG 0
DeleteRegKey HKLM "SOFTWARE\Classes\Prog"
YESREG:
DeleteRegKey /ifempty HKLM "SOFTWARE\Classes\Prog"
!macroend
Error: label "YESREG:" already declared in section

Такая конструкция работает, но это ужас:
!macro Test
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\1" "Name"
StrCmp $0 "My" +12 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\2" "Name"
StrCmp $0 "My" +10 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\3" "Name"
StrCmp $0 "My" +8 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\4" "Name"
StrCmp $0 "My" +6 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\5" "Name"
StrCmp $0 "My" +4 0
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\6" "Name"
StrCmp $0 "My" +2 0
DeleteRegKey HKLM "SOFTWARE\Classes\Prog"
DeleteRegKey /ifempty HKLM "SOFTWARE\Classes\Prog"
!macroend

iglezz
26-10-2023, 19:24
Подскажите пожалуйста, как средствами NSIS переконвертировать(сделать читабельной) последовательность символов (Unicode Escape), к примеру такого вида : \u0412\u0430\u043b\u0435\u043d\u0442\u0438\u043d ? »
ShowInstDetails show
RequestExecutionLevel user
InstallColors /windows
SetFont 'Fira Code Retina' 9
ChangeUI all '${MYNSISDIREXAMPLES}\Contrib\UIs\largelog.exe'

!include LogicLib.nsh
!include Util.nsh

!define SetSystemPluginDestination `!insertmacro SetSystemPluginDestination `
!macro SetSystemPluginDestination gflag value
!define ${gflag} ${value}
!if ${value} == 's'
!else if ${value} S== 'r0'
!else if ${value} S== 'r1'
!else if ${value} S== 'r2'
!else if ${value} S== 'r3'
!else if ${value} S== 'r4'
!else if ${value} S== 'r5'
!else if ${value} S== 'r6'
!else if ${value} S== 'r7'
!else if ${value} S== 'r8'
!else if ${value} S== 'r9'
!else if ${value} S== 'R0'
!else if ${value} S== 'R1'
!else if ${value} S== 'R2'
!else if ${value} S== 'R3'
!else if ${value} S== 'R4'
!else if ${value} S== 'R5'
!else if ${value} S== 'R6'
!else if ${value} S== 'R7'
!else if ${value} S== 'R8'
!else if ${value} S== 'R9'
!else
!define /redef ${gflag} 's'
!endif
!macroend

!define ChrW `!insertmacro ChrW `
!macro ChrW result int
!ifndef CharConvertBuffer16Initialized
!define CharConvertBuffer16Initialized
Var /GLOBAL g_CharConvertBuffer16
System::Call '*(&i2)p.s'
Pop $g_CharConvertBuffer16
!endif
${SetSystemPluginDestination} ${__MACRO__}SymbolDestination ${result}
System::Call '*$g_CharConvertBuffer16(&i2 ${int})'
System::Call '*$g_CharConvertBuffer16(&w1 .${${__MACRO__}SymbolDestination})'
!if ${${__MACRO__}SymbolDestination} == 's'
Pop ${result}
!endif
!undef ${__MACRO__}SymbolDestination
!macroend

!define StrUnicodeUnescape `!insertmacro StrUnicodeUnescape `
!macro StrUnicodeUnescape result str
!if '${str}' != 's'
Push '${str}'
!endif
${CallArtificialFunction} StrUnicodeUnescape_
!if ${result} != 's'
Pop ${result}
!endif
!macroend

!macro StrUnicodeUnescape_
Exch $0 ; [in] EscapedUnicodeString / [out] UnescapedUnicodeString
Push $1 ; / EscapedUnicodeString
Push $2 ; Counter
Push $3 ; GetChar
Push $4 ; GetChar2

StrCpy $1 $0
StrCpy $0 ''
StrCpy $2 -1

${Do}
IntOp $2 $2 + 1
StrCpy $3 $1 1 $2
${IfThen} $3 == '' ${|} ${ExitDo} ${|}
${If} $3 == '\'
IntOp $4 $2 + 1
StrCpy $4 $1 1 $4
${If} $4 == 'u'
IntOp $2 $2 + 2
StrCpy $3 $1 4 $2
IntOp $2 $2 + 3
${ChrW} r3 0x$3
${EndIf}
${EndIf}
StrCpy $0 $0$3
${Loop}

Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
!macroend

Section
StrCpy $1 '\u0412\u0430\u043b\u0435нт\u0438\u043d'
DetailPrint '>> [$1]'

${StrUnicodeUnescape} $0 $1
DetailPrint "<< [$0]"

Push $1
${StrUnicodeUnescape} $0 s
DetailPrint "<< [$0]"

Push $1
${StrUnicodeUnescape} s s
Pop $0
DetailPrint "<< [$0]"
SectionEnd

iglezz
26-10-2023, 20:55
Error: label "YESREG:" already declared in section »
Препроцессор раскрывает !insertmacro в содержимое макроса. Поэтому, если макрос используется более одного раза в секции/функции, происходит дублирование меток и ошибка.

Возможные решения:

1. Применять функции.
Параметры передавать нужно через стек. А также делать раздельные функции для install/uninstall или писать дополнительную логику для объявления функции в install и/или uninstall.

2. Применять вызов через ${CallArtificialFunction} (Util.nsh)
Параметры передавать нужно через стек. Реализация через установку метки и Goto на неё делает невозможным воздействие на код макроса флагами извне отдельно на каждый вызов, но это скорее понадобится для создания библиотечных макросов со сложной логикой.

3. Добавить в качестве префикса к метке уникальное в пределах текущего вызова макроса значение.
LogicLib.nsh использует такой метод (но в отличной от примера реализации).
!macro DigitIsOdd return value
; объявить префикс
!define LABEL__ ${__MACRO__}.__LABEL__.${__COUNTER__}

StrCmp '${value}' 1 ${LABEL__}YES 0
StrCmp '${value}' 3 ${LABEL__}YES 0
StrCmp '${value}' 5 ${LABEL__}YES 0
StrCmp '${value}' 7 ${LABEL__}YES 0
StrCmp '${value}' 9 ${LABEL__}YES 0
Goto ${LABEL__}NO

${LABEL__}YES:
StrCpy ${return} 'yes'
Goto ${LABEL__}EXIT

${LABEL__}NO:
StrCpy ${return} 'no'

${LABEL__}EXIT:

; удалить префикс
!undef LABEL__
!macroend


4. Изменить структуру кода, использовать LogicLib, если это возможно и не ухудшает читаемость кода.

MKN
27-10-2023, 11:23
iglezz, - замечательно ! (и где такому "волшебству" учат ? :) )
Некоторые детали кода не оч. понятны... largelog.exe в моих дистр-ах NSIS отсутствует(нужен для лога-проверки ?)
Почему на выходе три варианта ${StrUnicodeUnescape} - "[$0]" ?
Будет ли декодироваться не кириллическая таблица символов ?

iglezz
27-10-2023, 14:21
MKN, Вся видимая сложность тут для ускорения и некоторых дополнительных плюшек. А так, тут нет никакой магии, только примитивный парсинг строки и знание, что с помощью плагина System можно преобразовывать код символа в символ и обратно.
Цикл в StrUnicodeUnescape_ очень простой, умеет обнаруживаь и преобразовывать последовательность \u#### в юникод-символ. Без каких либо дополнительных проверок на корректность читаемых данных. По хорошему, надо, как минимум, добавить проверку на то, что после '\u' есть ровно четыре символа, которые являются валидным hex-числом.

largelog.exe - это мой специальный тестовый UI большего размера (230% оригинала) для дебага через DetailPrint.
Три варианта демонстрируют возможность читать строку со стека и записывать результат в стек. Это может быть полезно в сочетании в вызовами WinAPI функций через System::Call.
Декодируются все коды формата \u####




© OSzone.net 2001-2012