Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
Пример бы посмотреть, самый простой. »
Код по ссылке компилируется и работает. С модификацией могут быть проблемы, но они решаемы.
Как считать путь к папке OCR? Пользователь может выбрать любое расположение папки. »
Считать откуда?
AlekseyPopovv
29-09-2023, 21:05
Считать откуда? »
С реестра. К примеру там будет такой путь:
WriteRegStr HKCU "${APPREG}\OCR" "LanguagesPath" "@ByteArray(D:/Programs/OCR)"
Как теперь его преобразовать в "D:\Programs\OCR"?
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
А лучше вообще удалить всё что в скобках...
Как преобразовать? »
Использовать ${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?
Как сменить имя и папку деинсталлятора, когда его запускаешь? »
Никак.
Если сильно надо, сделать дополнительный скрипт, который будет служить в этой роли.
И если я просто его запускаю и отменяю удаление, то всё это остаётся в папке $TEMP. Как всё это удалить? »
В случае запуска с админскими привилегиями un.exe и каталог удаляются при перезагрузке.
Для простого юзера нужно колхозить подчистку.
Как изменить размер окна инсталлятора на всех страницах без правки русурсов и плагина NsResize? »
Зачем?
Простейший способ подчистки за исполняемым файлом - запуск скрытого процесса перед завершением работы: :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 и возвращаюсь на предыдущую страницу, потом обратно на следующую и галочка опять стоит.
Как сохранить статус 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
Всем хорошего дня.
Если на рабочем столе кликнуть правой кнопкой мыши, то там есть пункт "Обновить". Как эту команду прописать в NSIS?
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)
Подскажите пожалуйста, как средствами 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
Подскажите пожалуйста, как средствами 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
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, если это возможно и не ухудшает читаемость кода.
iglezz, - замечательно ! (и где такому "волшебству" учат ? :) )
Некоторые детали кода не оч. понятны... largelog.exe в моих дистр-ах NSIS отсутствует(нужен для лога-проверки ?)
Почему на выходе три варианта ${StrUnicodeUnescape} - "[$0]" ?
Будет ли декодироваться не кириллическая таблица символов ?
MKN, Вся видимая сложность тут для ускорения и некоторых дополнительных плюшек. А так, тут нет никакой магии, только примитивный парсинг строки и знание, что с помощью плагина System можно преобразовывать код символа в символ и обратно.
Цикл в StrUnicodeUnescape_ очень простой, умеет обнаруживаь и преобразовывать последовательность \u#### в юникод-символ. Без каких либо дополнительных проверок на корректность читаемых данных. По хорошему, надо, как минимум, добавить проверку на то, что после '\u' есть ровно четыре символа, которые являются валидным hex-числом.
largelog.exe - это мой специальный тестовый UI большего размера (230% оригинала) для дебага через DetailPrint.
Три варианта демонстрируют возможность читать строку со стека и записывать результат в стек. Это может быть полезно в сочетании в вызовами WinAPI функций через System::Call.
Декодируются все коды формата \u####
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.