Синтаксис:RMDir [/r] [/REBOOTOK] directory_name
Удалить указанный каталог (полный путь без подстановочных знаков). Без /r
каталог будет удален только в том случае, если он полностью пуст. Если указан параметр /r
, каталог будет удален рекурсивно, поэтому будут удалены все каталоги и файлы в указанном каталоге. Если указан параметр /REBOOTOK
, любой файл или каталог, которые не удалось удалить во время процесса, будут удалены при перезагрузке — если какой-либо файл или каталог будут удалены при перезагрузке, будет установлен флаг перезагрузки. Флаг ошибки устанавливается, если какой-либо файл или директория не могут быть удалены.
Пример:RMDir $INSTDIR
RMDir $INSTDIR\data
RMDir /r /REBOOTOK $INSTDIR
RMDir /REBOOTOK $INSTDIR\DLLs
Обратите внимание, что текущий рабочий каталог (с экзешником) нельзя удалить. Текущий рабочий каталог устанавливается SetOutPath
. Например, следующий пример не удалит каталог:SetOutPath $TEMP\dir
RMDir $TEMP\dir
В следующем примере удастся удалить каталог:SetOutPath $TEMP\dir
SetOutPath $TEMP
RMDir $TEMP\dir
Предупреждение: использование RMDir /r $INSTDIR
в деинсталляторе небезопасно. Хотя это маловероятно, пользователь может выбрать установку непосредственно в папку Program Files
, и поэтому эта команда сотрет всю папку Program Files
, включая другие программы, которые не имеют ничего общего с установленной программой.
Доступны решения для более безопасного простого удаления только тех файлов, которые были установлены установщиком.
Перевод: Kolyan Maloy aka Dzhan for tolik-punkoff.com
Источник: NSIS Wiki
Это репост с сайта http://tolik-punkoff.com
Оригинал: https://tolik-punkoff.com/2023/04/16/nsi
Page Summary
October 2025
|
NSIS: Удалить каталог полностью с файлами и подкаталогами (RMDir)
NSIS: поиск и завершение (kill) внешнего процесса.
Делается с помощью плагина 1. Качаем архив 2. Распаковываем содержимое архива по соответствующим каталогам NSIS NsProcess.zip\Example --> C:\Program Files (x86)\NSIS\Examples\nsProcess Начало: Unicode true Немного дополнил пример из официального мануала, вставив макрос для расширенного вывода сообщений об ошибках: !macro PrintProcError ErrCode Код разлапистый, потому на PasteBin: !macro PrintProcError ErrCode Код внутри секции: 1. Запускаем тестовую программу ( calc.exe , которая обычно есть в любой винде и лежит она обычно в $SYSDIR , т.е. в C:\Windows\System32\ ) и ждем 500 миллисекунд:DetailPrint "Start calc.exe..." 2. Спрашиваем у пользователя, будем ли убивать процесс. Если нет - идем на завершение: MessageBox MB_YESNO|MB_ICONQUESTION "Kill process calc.exe?" IDYES 0 IDNO "EndProg" 3. Ищем процесс(ы) по имени экзешника: DetailPrint "Find process calc.exe..." Да, можно хоть 10 калькуляторов назапускать. 4. Вытаскиваем из стека результат функции _FindProcess :Pop $R0 5. Выводим на псевдоконсоль расшифровку кодов возврата: !insertmacro PrintProcError $R0 6. Если код возврата = 0 , значит, процесс найден, пытаемся его убить, выводим расшифровку кодов возврата, и опять подождем 500 миллисекунд:
![]() На GitHub - Официальная справка плагина (на буржуйском) - Перевод от Leha Silent (копия) Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2023/04/02/nsi Плагин NsProcess
Версия 1.5: - nsProcess.zip (25 KB) Версия 1.6 (поддержка NSIS UNICODE от brainsucker, переименуйте библиотеку nsProcessW.dll ):- nsProcess.zip (14 KB) - Зеркало: nsProcess_1_6.7z Обсуждение: На форуме Возможности: - Поиск процесса по имени. - Завершение всех процессов с указанным именем (все найденные экземпляры). - Закрытие всех процессов с указанным именем. Сначала происходит попытка закрыть все окна процессов, ожидание 3 секунд для завершения процессов. Если процесс(ы) все еще активны, используйте функцию _CloseProcess .- Имя процесса нечувствительно к регистру - Поддерживаемые ОС: Win95/98/ME/NT/2000/XP/Win7 - Поиск процессов других пользователей при запуске с правами администратора или при переключении на другого пользователя. - Маленький размер плагина (4 Кб) - Поддержка Unicode (просто переименуйте nsProcessW.dll в nsProcess.dll )
Обычно _FindProcess возвращает:- 0 если процесс найден- 603 если процесс(ы) не найдены
Ravi Kochhar (исходная функция FIND_PROC_BY_NAME на основе его кода) iceman_k (Find Process By Name) и DITMan (KillProcDLL Manual). Перевел Leha Silent специально для tolik-punkoff.com Источник Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2023/04/02/pla Патч на NSIS (с возможностью отмены).
На самом деле, многими реверсерскими командами создана куча генераторов автопатчеров, подсовываешь ему оригинальный и измененный экзешник, и тебе генерируется автопатчер, даже с красивой картинкой и восьмибитной музыкой. Но "есть проблема" (ц) Патриарх Кирилл: - Не на все автопатчеры хорошо реагируют антивирусы - Автопатчеры нестандартны, кто в лес, кто по дрова. Неплохо бы сделать так, чтоб и антивирусы не ругались, и оно хоть как-то относительно стандартно выглядело. И такое решение есть - модуль VPatch для системы установки NSIS. Далее расскажу, как этим модулем воспользоваться, чтобы пропатчить уже установленную программу, а также, немного расширю пример, покажу как в патч "зашить" еще и отмену патча. Естественно, чтобы все повторить, у вас должен быть установлен NSIS хотя бы в минимальной комплектации. Устанавливаем модуль VPatch, лучше воспользоваться ссылкой на установщик, потом скачать родной пример и попытаться его скомпилировать. Если все сработало - модуль установился правильно, можно работать дальше. Для генерации данных для патча, VPatch использует свои утилиты командной строки, которые в комплекте идут, но устанавливаются криво, так что качаем утилиты отдельно и устанавливаем их (установятся в %WINDIR% ).Скачать установщик здесь Теперь нужна лабораторная крыса, т.е. программа, которую будем патчить, возьмем оригинальный CrackMe из предыдущего примера (копия) и напишем ему стандартный инсталлятор: Исходник инсталлятора Готовый инсталлятор тестовой программы Исходник CarckMe Устанавливаем ее. Для патча нужен оригинальный экзешник И пропатченный вручную ( Подробное описание патча ) Патч: ![]() Восстановление: ![]() - VPatch - Free Patch Generator - VPatch plug-in - Документация и исходники оригинального примера - NSIS: контрольная сумма (MD5), сравнение файлов. (копия) - NSIS: Получение списка файлов с MD5-хешами. (копия) - NSIS: Получение даты и времени. (копия) Пример полностью на GitHub Основной исходник Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2023/03/30/pat NSIS: Получение даты и времени.
Иногда бывает нужно получить в скрипте установки локальную дату и время, или дату и время, связанную с файлом (модификации, создания или последнего доступа к файлу). В NSIS это делает одна стандартная функция, точнее, макрос ${GetTime} .Для того, чтобы использовать GetTime , необходимо подключить заголовочный файл FileFunc.nsh (должен идти в стандартной поставке) и сам макрос GetTime :!include "FileFunc.nsh" Вот начало инсталляционного скрипта: Unicode true ${GetTime} "[File]" "[Option]" $var1 $var2 $var3 $var4 $var5 $var6 $var7 где: - "[File]" - файл (параметр игнорируется при использовании опций "L" или "LS" )- "[Option]" - опции (см. далее)- $var1 - День- $var2 - Месяц- $var3 - Год- $var4 - День недели (наименование на английском языке)- $var5 - Час- $var6 - Минута- $var7 - СекундаОпции: L - локальное время компьютераA - время последнего доступа к файлуC - время создания файлаM - время последнего изменения файлаLS - системное время (то же самое, что и L , только используется часовой пояс UTC)AS - время последнего доступа к файлу (UTC)CS - время создания файла (UTC)MS - время последнего изменения файла (UTC)
![]() - Пример на GitHub - how to get the date and time? - E.1.6 GetTime Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2023/03/19/nsi NSIS: Получение списка файлов с MD5-хешами.
Как-то показывал, как в NSIS получить MD5-хэши (копия), файлов в т.ч. Решил расширить пример, а как получить список файлов в каталоге и их MD5-хэши. Мне пригодится для следующего примера по NSIS, но и народ спрашивал, ибо в вышеуказанном примере нельзя выбрать произвольный файл, или сразу несколько. Исправляемся. Перед тем, как обработать какие-то файлы, надо их сначала найти и как-то передать в инсталлятор. В NSIS есть для этого несколько способов: - Использовать стандартные функции FindFirst/FindNext , которые работают почти также, как соответствующие функции в WinAPI и требуют городить довольно неудобочитаемый цикл, постоянно проверять ошибки.- Рекомендуемый разработчиками NSIS способ: использовать плагин Locate, работа с которым тоже отличается довольно неудобочитаемым кодом, и работает он в некоторых случаях не совсем стабильно. - Функция Locate , которую вообще-то должен был заменить вышеуказанный плагин, но, как по мне, заменил ее криво. Ей проще воспользоваться, во всяком случае, для такой небольшой задачи. Далее будем работать именно с функцией Locate .1. Создаем файл Locate.nsi в каталоге проекта, помещаем в него код функции, который можно взять их официальной Wiki NSIS. Раздел Function Code. (копия на PasteBin копия на GitHub)2. Создаем основной файл ( MD5List.nsi ), формируем "болванку" проекта:Unicode true Не забываем подключить файл с кодом функции Locate (Locate.nsi ): !include "Locate.nsi" ${Locate} "[Path]" "[Options]" "Function" где: "[Path]" - путь, стартовый каталог для поиска"[Options]" - опции (см. далее)"Function" - callback-функция (см. далее)/L=[FD|F|D|DE|FDE] - что искать:/L=FD - Найти файлы и каталоги (по умолчанию) /M=[маска_файла] .По умолчанию /M=*.* (все файлы)Можно изменить, например на /M=*.txt (текстовые файлы), и т.д./S= Размер файла. Не буду заострять на этом внимание, синтаксис этой опции можно посмотреть оригинальной документации. По умолчанию размер файла игнорироуется. /G=[1|0] - поиск с подкаталогами:/G=1 - включить поиск с подкаталогами (включен по умолчанию)/G=0 - поиск только в текущем каталоге${Locate} "C:\SOMEDIR" "/L=F" "Userfunction" Где мы указали каталог, с которого нужно начать поиск, указали хоть одну опцию, нужно указать хотя бы одну, и указали функцию обратного вызова, пока имя условное, но ниже объясню. Это пользовательская функция, которая должна получать данные от ${Locate} , а далее уж сама их обрабатывать.${Locate} передает в функцию следующие стандартные переменные:$R9 - полный путь к файлу$R8 - путь без имени файла$R7 - имя файла$R6 - размер (для каталога $R6==0 )Остальные глобальные переменные можно использовать для своих целей внутри функции. Внимание: callback-функция для ${Locate} обязательно должна заканчиваться командой push <переменная> .Чтобы завершить функцию нормально, необходимо положить любое значение в стек: push $0 Всегда помещайте что-либо в стек (даже если вы не собираетесь останавливать поиск), иначе произойдет непредвиденное! Чтобы прервать поиск до того, как он завершится сам, в стек надо поместить значение StopLocate :StrCpy $0 StopLocate Внимание! Внутри callback-функции почему-то не работает DetailPrint .Теперь, зная все вышеозначенное, можно писать основной код. Полученные данные будем писать во временный файл, раз уж DetailPrint нельзя воспользоваться. Получаем имя для временного файла и открываем его для записи:GetTempFileName $R0 Начинаем поиск: DetailPrint "Starting search files and get MD5..." $INSTDIR - каталог, который выберет пользователь при запуске примера."/L=F /M=*.*" - /L=F - ищем только файлы /M=*.* - все файлы."GetMD5" - имя callback-функции (см. ниже)По окончанию поиска закрываем файл: FileClose $R1 И проверяем, не случилось ли ошибок. Если случилось, выводим окно с надписью Error, если не случилось - открываем полученный файл в Блокноие: IfErrors 0 +2 Код секции целиком После секции организуем пользовательскую функцию:
Скормим программе ее же каталог. ![]() В Блокноте откроется временный файл со следующим содержимым:
- NSIS: контрольная сумма (MD5), сравнение файлов. (копия) - Locate на NSIS Wiki - Пример на GitHub Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2023/03/15/nsi Утилиты для создания автоматического патча на NSIS
Один из пользователей NSIS создал проект VPatch, который позволяет на NSIS написать автоматический патчер (после покажу пример, а может даже парочку). Но устанавливается он как-то криво, консольные утилиты, которыми генерятся данные для будущего патча устанавливаются абы куда, а не в какой-нибудь Отключение обновления Foxit PDF Reader (v. 8.3.2.25013)
![]() Когда-то писал о том, что в новых версиях Foxit Reader пропал PDF-принтер и Foxit PDF Creator (копия). Так вот, новая гадость пришла откуда не ждали, теперь он сносит PDF-принтер при обновлениях. Штатного способа отключить обновления нет Сама программа обновления имеется в двух экземплярах: В каталоге Foxit: C:\Program Files (x86)\Foxit Software\Foxit Reader\FoxitUpdater.exe И в каталоге Application Data : C:\Users\<username>\Application Data\Foxit Software\Addon\Foxit Reader\FoxitReaderUpdater.exe , вместо <username> - ваше имя пользователя.Просто снести два экзешника не получится, точнее получится, но Foxit Reader будет при каждом запуске ругаться, что не нашел свой обновлятор. Зато не будет ругаться, если обновлятор (оба файла) просто заменить на экзешник, который ничего не делает, а такой я уже делал (копия), правда по другому поводу. Сделал еще и версию на MASM И для себя, если винды переустанавливать, и для клиентов, на всякий случай. Репозиторий на GitHub Исходник NSIS Копия (без дополнительных файлов) на PasteBin Скачать готовый патч В принципе, исходник достаточно простой, оставлю только ссылку на получение MD5-суммы файла в NSIS: NSIS: контрольная сумма (MD5), сравнение файлов. (копия). Примечание: почему-то MD5-сумма, получаемая NSIS-плагином (md5dll.dll) отличается от MD5-суммы, полученной средствами Windows (копия). Почему, пока не разобрался. Может, позже напишу. Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2022/06/13/otk NSIS: контрольная сумма (MD5), сравнение файлов.
В принципе, патч или кряк для программы можно сделать с помощью NSIS, конечно, это будет не классический патч, т.е., когда меняешь в исходном экзешнике несколько байт, а архив с готовым экзешником и сценарием установки. Но зато и возможностей больше, можно Реестр или INI-файлы подправить, например. Но одна из главных задач любого патча, перед началом работы проверить, а не пропатчен ли файл уже. Делается это обычно так - берется контрольная сумма MD5 или CRC32 оригинального файла и сравнивается с заранее известной суммой. Если совпадает - файл наш, можно патчить. Можно и наоборот - сравнить контрольную сумму оригинального файла с известной контрольной суммой пропатченного, если они равны - файл уже модифицирован, сообщаем пользователю и завершаем работу. Для получения MD5 в NSIS имеется плагин MD5 Plugin. Скачиваем архив, копируем md5dll.dll из директории ANSI архива в директорию ANSI-плагинов NSIS (у меня C:\Program Files (x86)\NSIS\Plugins\x86-ansi\ ), а из директории UNICODE архива в директорию UNICODE-плагинов (C:\Program Files (x86)\NSIS\Plugins\x86-unicode ). Понятно, что пути к вашим каталогам плагинов могут отличаться, т.к. зависят от того, куда установлен NSIS/Вычисление контрольной суммы строки: #generate MD5sum of string Вывод: MD5 (string): [5b56f40f8828701f97fa4511ddcd25fb] Получение случайного хэша MD5: #generate random MD5sum Вывод: MD5 (random): [864fd151525efad56947f25fa3daeb75] Получение контрольной суммы файла: #generate MD5sum of file Вывод: MD5 sum of file C:\!\Installers\MD5Sample\test\1.exe Для более красивого кода сравнения, рекомендую подключить инклюд с макросами логических операторов LogicLib.nsh (есть в комплекте NSIS):!include LogicLib.nsh Пример:
Пример вывода (сравниваются два одинаковых файла, а потом два разных): Files C:\!\Installers\MD5Sample\test\1.exe Если файл отсутствует, то функция md5dll::GetMD5File может выдать непредсказуемый результат, строку случайных символов, поэтому, перед использованием md5dll::GetMD5File следует проверять наличие и доступность файлов.![]() Библиотека: - Описание на официальном сайте: MD5 plugin - Скачать с официального сайта - Зеркало - Копия (v 0.5) на Mega.nz Пример из заметки целиком на GitHub Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2022/05/10/nsi NSIS: Сохранение лога установки в текстовый файл.
На самом деле, не совсем сохранение лога, если быть точным - сохранение текста из окна Details установщика. NSIS Wiki Код на GitHub dumplog.nsi Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2020/11/13/nsis-s NSIS. Проверка существования ключа Реестра.
Иногда бывает надо проверить, существует тот или иной ключ Реестра Windows Для этого можно воспользоваться стандартной функцией EnumRegKey :EnumRegKey <var> <root_key> <subkey> <index> где: <var> - переменная для названия ключа Реестра, которое будет возвращено функцией.<root_key> - корневой ключ Реестра (HKCR|HKCU|HKLM|HKU|HKCC )<subkey> - путь в Реестре, например Software\Microsoft\Windows <index> - индекс следующего ключа.Функция перебирает все подключи в указанной ветке Реестра. Пример для перечисления можно посмотреть здесь Если ключ не существует, то функция EnumRegKey сгенерирует ошибку, которую можно отследить:
Пример целиком на GitHub Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2020/11/12/nsis-p NSIS: Создание точки восстановления системы.
В некоторых случаях, например, при установке драйверов, необходимых для работы вашей программы, или при внесении серьезных изменений в систему, хотелось бы задействовать механизм создания точек восстановления, чтобы в случае непредвиденной ситуации, пользователь мог бы безболезненно откатить все назад. Как, например, поступает Driver Pack Solutions перед установкой драйверов. Для создания точек восстановления в NSIS применяется плагин SysRestore, который можно скачать с официальной NSIS wiki (копия). Установка тривиальна - надо распаковать архив в каталог NSIS, например в "C:\Program Files (x86)\NSIS\" После подключения плагина становятся доступны 4 функции: SysRestore::StartInstallPoint "<название>" - функция создает точку восстановления с типом "Установка", применяется для создания точки восстановления при установке программы.![]() SysRestore::StartUninstallPoint "<название>" - функция создает точку восстановления с типом "Удаление", применяется для создания точки восстановления при удалении программы.В стек эти функции (как и другие функции данного модуля) помещают код возврата, который можно извлечь из стека командой Pop <переменная> И далее проанализировать: 0 - Функция завершена успешно, точка восстановления создана.1 - Уже запущено создание точки восстановления, предыдущую точку восстановления надо закрыть или отменить (см. ниже).10 - Windows запущена в "Безопасном режиме"13 - The sequence number is invalid (сам автор плагина не знает, что это за ошибка).80 - Ошибка с таким кодом встречается в Windows ME.112 - Восстановление системы находится в режиме ожидания, поскольку закончилось место на жестком диске под точки восстановления.1058 - Восстановление системы отключено.1359 - Внутренняя ошибка при создании точки восстановления.1460 - Время ожидания вызова истекло из-за ожидания мьютекса для установки точек восстановления (вот это уже я не знаю, что такое).Впрочем, про коды ошибок, автор пишет следующее: Я не знаю, являются ли эти коды актуальными кодами ошибок, я просто проанализировал соответствующие include-файлы в SDK. Я тестировал код 1058 - восстановление системы отключено, и провел тест в безопасном режиме - код ошибки 10, я предполагаю, что эти коды верны. Так что возможно ограничиться анализом кодов 0 (ОК), 1 (см. ниже), 10 (безопасный режим) и 1058 (восстановление системы отключено). Если функция выдаст что-то кроме этих четырех понятных кодов, остальное можно (в первом приближении) отправить в великий класс Неизвестная Ошибка (Unknown Error). Хотя, если вы знаете больше, чем автор плагина, а тем более, чем я - добро пожаловать в комментарии. Кроме вышеперечисленных инициализирующих функций, существует "закрывающая" и "отменяющая" функции. "Закрывающая": SysRestore::FinishRestorePoint Ее необходимо вызывать, после того, как все изменения в системе произведены, чтобы закрыть точку восстановления, и чтобы система получила нужные данные о том, что было изменено в системных/программных файлах и Реестре. Попытка создать новую точку восстановления без закрытия предыдущей, в одном и том же инсталляторе, приводит к тому что функции StartInstallPoint/StartUninstallPoint выдадут ошибку 1 .Как я понимаю, система все равно закроет restore point после завершения работы установщика, но лучше эту функцию использовать. "Отменяющая" функция, это: SysRestore::RemoveRestorePoint Она позволяет удалить незакрытую точку восстановления из системы. Может понадобиться в случае, если пользователь отменил установку в процессе, и установщик откатил процесс установки. Коды возврата последних двух функций: 0 - OK2 - Не произведен запуск точки восстановления (т.е. предварительно не вызваны функции StartInstallPoint или StartUninstallPoint )В первой секции... Вообще, для этого можно создать скрытую секцию, чтоб сначала создать restore point, а потом с ней работать далее, но пример простой, так что в первой секции, до начала изменений, создаем точку восстановления
Тестовый установщик создает точку восстановления, далее устанавливает во временный каталог системы программу, которая при запуске показывает приветственное окно и завершает работу, прописывает ее в автозагрузку Реестра, и генерирует uninstaller во временном каталоге. Код на GitHub Скомпилированный инсталлятор 1. NSIS Wiki 2. Копия (на 07.11.2020) Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2020/11/08/nsis-s NSIS warning 7998: ANSI targets are deprecated, как исправить.
Обновил NSIS с v 3.04 до 3.06.1, в логе компилятора стал вылезать warning:
Т.е. ANSI ему устарело. Warning не error, но все равно неприятно. Впрочем, исправить не составило особого труда. Для исправления этого дела, в начало скрипта надо добавить команду: Unicode true Только команду надо добавлять в самое начало скрипта, во всяком случае до секций и до определения параметра InstallDir . Если добавить после InstallDir :;... То это вызовет ошибку: Error: Can't change target charset after data already got compressed or header already changed! Невозможно изменить целевую кодировку после того, как данные уже сжаты или заголовок изменен! А лучше добавлять Unicode true вообще в самое начало скрипта, первой строчкой, даже до !include , как пишут на форуме NSIS, т.к. от чего компилятор так реагирует на смену кодировки, в документации не описано.Примечание: с русским языком в инсталляторе проблем при смене кодировки не случилось, хотя редактор передает компилятору скрипт на STDIN , а редактор сохраняет файл скрипта в ANSI (кодировка Win 1251). Во всяком случае, проблем не случилось при использовании Venis IX.![]() Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2020/11/07/nsis-w NSIS: Отслеживание кода возврата исполняемого приложения.
В процессе установки иногда приходится вызывать внешние приложения, например, какую-нибудь утилиту для настройки системы, и так далее. При вызове внешней программы надо отследить ее работу, завершена ли она корректно, или же в процессе выполнения произошла ошибка. Могу привести довольно древний пример из своего опыта, когда-то программы распространялись на CD, и производитель материнской платы давал диск с "бонусным" софтом. Но в инсталлятор была встроена программа, определявшая модель материнской платы - если модель не совпадала, установщик "халявных" программ отказывался что-либо устанавливать. Когда я распаковал установщик и проанализировал это дело, выяснилось, что установщик сначала распаковывал и запускал внешнюю утилиту, которая проверяла модель мать-доски. И возвращала код выхода: 0 - правильная мать-доска, 1 - неправильная.Вызов внешнего приложения выполняется командой ExecWait "путь_и_имя_файла параметры_программы" [переменная_для_кода_возврата] Например: ExecWait "$TEMP\retcode.exe 42" Второй параметр - переменная для сохранения кода возврата вызванной программы, т.е. если мы хотим вызывать программу и анализировать ее код завершения, надо действовать так: ;... Далее анализируем содержимое переменной $0 .Пример инсталлятора на GitHub Reference/ExecWait Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2020/11/05/nsis-o Преобразование REG-файла в код скрипта инсталлятора NSIS
Понадобилось тут добавить ключи из REG-файла в код своего инсталлятора на NSIS. Оказывается, все придумано до нас. Имеется утилита Reg2Nsis, которая этим и занимается. reg2nsis REG-файл [ПАРАМЕТРЫ] или reg2nsis ключ_реестра [ПАРАМЕТРЫ] Т.е. утилита может преобразовать в код NSIS, как содержимое REG-файла, так и данные непосредственно из реестра. Параметры: -r - обработать ключ реестра со всеми подключами, начиная с указанного. Срабатывает только если в качестве источника указан путь в реестре.-o <файл> - код будет сохранен в указанный файлЕсли вместо -o <файл> указать ключ -O , то код будет сохранен в файл с именем, аналогичным указанному REG-файлу, но с расширением .nsh Без дополнительных параметров, код NSIS будет выведен на консоль ( stdout )Программа смотрит в настройки системы и автоматически преобразует стандартные системные пути в стандартные переменные NSIS. Например, встретившийся путь C:\Windows\ будет преобразован в $WINDIR\ . Это можно отключить, добавив в командной строке ключ -s .При анализе REG-файла, программа распознает как добавление ключа/значения, что понятно, так и команду на его удаление. Т.е. запись в REG-файле: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentContro будет преобразована в: WriteRegStr HKEY_LOCAL_MACHINE "SYSTEM\CurrentControlSet\services\oem-d А запись: [-HKEY_LOCAL_MACHINE\SYSTEM\CurrentContr преобразуется в следующий код: DeleteRegKey HKEY_LOCAL_MACHINE "SYSTEM\CurrentControlSet\services\oem-d С официальной NSIS-wiki Копия на mega.nz Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2020/11/04/preo NSIS: продолжение установки после перезагрузки.
Например, у нас есть софтина, которая в процессе своей установки требует перезагрузку, после чего доустанавливается. Например, софт устанавливает свой драйвер, обновление, или же регистрирует системный сервис. Как реализовать инсталлятор для такой программы? Изначально я хотел обойтись параметрами командной строки, добавляемыми при запуске установщика, но с ними произошла жопа, поэтому будем действовать более надежными методами. 0. Проверяем наличие уникального ключа Реестра, сигнализирующего о том, что надо выполнить вторую часть установки (после перезагрузки): DetailPrint "Read After Reboot flag..." 1. Производим все действия, которые необходимо произвести до перезагрузки (устанавливаем драйвера, регистрируем DLL и т.д.) 2. Записываем в однократную автозагрузку (ключ Реестра RunOnce ) наш инсталлятор, путь к exe файлу инсталлятора, который можно взять из переменной $EXEPATH .Автозагрузку прописываем для текущего пользователя (пользователя, запустившего установщик), т.е. в ключ HKEY_CURRENT_USER .WriteRegStr HKCU Примечание: В RunOnce могут записаться программы, которые требуется выполнить однократно при загрузке системы. После выполнения программ, ключ RunOnce очищается автоматически, что отличает его от ключа Run , где данные не очищаются, и его можно использовать, как постоянную автозагрузку.3. Устанавливаем уникальный флаг, по которому будем определять, что инсталлятор был запущен после перезагрузки, например, таким образом: DetailPrint "Write After Reboot flag..." 4. Выдаем запрос на немедленную перезагрузку: DetailPrint "Reboot request." Если пользователь ответил " Yes ", сразу перезагружаемся:
Если нет, ждем перезагрузки вручную: DetailPrint "Installation continue if user restart system." 5. После перезагрузки удаляем флаг (проверив его наличие, см выше): DetailPrint "Delete After Reboot flag..." 6. И продолжаем установку... DetailPrint "Continue install after reboot..." ![]() ![]() ![]() На GitHub Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/08/12/nsis-p Глюк в NSIS: проверка параметров командной строки инсталлятора не работает
Вот серьезно, бьюсь (головой об стену) уже третий день, ну не работает функция Глюк (недоработка) uninstaller'а NSIS.
Или как поместить uninstaller не в директории программы. Конечно, возникает вопрос "зачем?". Ну, например, мы устанавливаем некое системное приложение, драйвер, или хотим что-то пропатчить. В качестве каталога по умолчанию для такого приложения может служить, например, директория $WINDIR (обычно C:\Windows ). Если мы хотим безболезненно удалить такое приложение, то нам нужно создать анинсталлер, но, совсем не обязательно чтоб он хранился в том же каталоге, что и установленное приложение. Зачем, например, загаживать каталог C:\Windows файлами uninstall.exe . Да в том то все и дело, что незачем, и вот тут мы сталкиваемся с глюками анинсталлера.В анинстайлере и инсталляторе переменная $INSTDIR определяется по-разному. В секции установки $INSTDIR можно задать, в т.ч. и автоматически, а в uninstaller'е она определяется, как директория, из которой запустился анинсталлер. Это довольно легко проиллюстрировать простым кодом, который на самом деле ничего не устанавливает, а просто предлагает пользователю выбрать каталог для установки, а сам выводит пути к каталогам и создает тестовый анинсталлер во временном каталоге. Анинсталлер тоже ничего не удаляет, просто выводит значения переменных, заданных в основном скрипте.Любые пользовательские переменные при работе uninstall так же "забываются", вне зависимости от того, были ли они определены в секции, или в скрипте вообще. Фрагмент кода из установщика:
Секция установки: 1. Заполняем $TESTVAR 2. Выходим значение $TESTVAR 3. Выводим значение $INSTDIR 4. Создаем Uninstall'ер, причем не в $INSTDIR ![]() ![]() В секции удаления выводим значения $INSTDIR и $TESTVAR , анинсталлер запускаем из временного каталога.
![]() Значение $INSTDIR изменилось на временный каталог, а значение $TESTVAR было потеряно. Если переместить анинсталлер в другой каталог, значение $INSTDIR опять поменяется.![]() Исходник, иллюстрирующий баг Из вышеизложенного напрашивается вывод, что значения $INSTDIR и нужных переменных надо сохранять на этапе установки, например в Реестр или INI-файл, а на этапе удаления восстанавливать.В следующем примере я буду сохранять нужные значения в INI-файл, который будет располагаться в директории с uninstall.exe , а сама программа будет устанавливаться в другой каталог. Сгенерирую простой скрипт мастером скриптов и немного подправлю.1. Меняем InstallDir на "$TEMP\TestApp" InstallDir "$TEMP\TestApp" 2. Заводим переменную $UNINSTDIR Var UNINSTDIR 3. В секции установки задаем ее значение, скажем "$PROGRAMFILES\TestApp" StrCpy $UNINSTDIR "$PROGRAMFILES\TestApp" 4. Создаем каталог $UNINSTDIR 5. Меняем где надо пути в создаваемых ярлыках CreateShortCut "$SMPROGRAMS\TestApp\Uninstall.lnk" "$UNINSTDIR\uninstall.exe" 6. ...путь для записи uninstall.exe WriteUninstaller "$UNINSTDIR\uninstall.exe" 7. ...и запись в Реестре для "Программ и компонентов" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersi 8. После создания uninstall.exe в каталоге $UNINSTDIR необходимо создать INI-файл, в который сохранить пути к каталогам $UNINSTDIR и $INSTDIR WriteINIStr "$UNINSTDIR\dirs.ini" "dirs" "I" "$INSTDIR" На этом с секцией установки закончили. В секции удаления: 1. Читаем значения из INI-файла (который для uninstall.exe будет располагаться в каталоге из переменной $INSTDIR ) в перезаписываемые переменные $0 и $1 . Если чтение не удалось, необходимо будет обработать ошибку (см. описания функций ReadINIStr и конструкции IfErrors в справочнике копия).ReadINIStr $0 "$INSTDIR\dirs.ini" "dirs" "I" 2. Восстанавливаем значения $INSTDIR и $UNINSTDIR :StrCpy $INSTDIR $0 3. Удаляем uninstall.exe , INI-файл и каталог анинсталлера:Delete "$UNINSTDIR\uninstall.exe" 4. Удаляем компоненты программы и ярлыки. 5. В конце секции заводим метку OK: 6. После удаления программы переходим в конец секции Goto OK 7. Перед меткой OK: заводим метку Dupa: , куда попадем если произошла ошибка чтения INI-файла. После метки Dupa: будет обработчик ошибки. В данном случае выводим пользователю сообщение о том, что INI-файл некорректный, и произвести автоматическое удаление программы нельзя.
1. Исходник, иллюстрирующий баг uninstaller'а 2. Исходник примера Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/07/28/glyu Справочник по NSIS с OSZone
Не сильно хороший, но пусть будет. NSIS: определение версии и архитектуры Windows
Одна из частых задач при создании инсталлятора - определить версию и архитектуру ОС, например, чтобы в зависимости от этого подкладывать нужную версию экзешника, или устанавливать нужный драйвер. Для отображения версии Windows можно воспользоваться готовым кодом из NSIS wiki. На выбор предоставлены два скрипта: только для клиентских ОС и для клиентских и серверных. Для своих целей я пользовался вторым, правда в нем есть небольшой баг - клиентская Windows XP x64 определяется как Windows Server 2003: ![]() Создаем отдельный пустой NSIS-скрипт, копируем туда код из wiki, и сохраняем в тот же каталог, где находится основной скрипт инсталлятора под любым удобным названием, например gvv.nsi .В основном скрипте подключаем этот файл: !include gvv.nsi Далее вызываем GetWindowsVersion , записываем результат в переменную (например, в предопределенную $R0 ) и выводим результат:${GetWindowsVersion} $R0 Так сказать, "точное" определение версии. Применяется, когда надо выполнить определенные действия, например, в XP и только в XP, или в семерке и только в семерке. Для этого в комплекте есть модуль WinVer.nsh , сначала подключим его:!include WinVer.nsh Далее используем if и один из макросов IsWin? , например IsWinXP , IsWin7 , IsWin10 :
Применяется, когда нужно выполнять код, если версия ОС выше нужной или нужная. В WinVer.nsh есть другой комплект макросов - AtLeastWin? (AtLeastWin7 , AtLeastWin8 , AtLeastWin10 ) которые также нужно использовать вместе с if . Например, следующий код сработает на "семерке" и всех последующих версиях Windows. В деталях установки отобразится соответствующее сообщение:
Для определения архитектуры ОС необходимо подключить модуль x64.nsh (также поставляется вместе с компилятором NSIS):!include x64.nsh Поддерживается определение архитектуры x86 ( IsNativeIA32 ), PC (AMD) x64 (IsNativeAMD64 ) и ARM64 (IsNativeARM64 ) пример кода есть в самом файле x64.nsh :) Мне ARM была не нужна, поэтому пример кода на три строки короче:
( Под катом ) На GitHub 1. Get Windows version 2. Stackoverflow Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/07/25/nsis-o |