Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
но громоздко в коде + известные недостатки... »
Я с самого начала об этом говорил, но человек спросил без сторонних разработок, средствами самого NSIS. Главное дать идею, а дальше уж пускай развивает её сообразно имеющемуся опыту и знаниям. :)
wolkow70
11-03-2014, 15:01
Не сложный макрос для проверки ключа реестра на наличие:
!include "LogicLib.nsh"
!macro IfKeyExists ROOT MAIN_KEY KEY
Push $R0
Push $R1
Push $R2
StrCpy $R1 "0"
StrCpy $R2 "0"
${Do}
EnumRegKey $R0 ${ROOT} "${MAIN_KEY}" "$R1"
${If} $R0 == "${KEY}"
StrCpy $R2 "1" # found
${Break}
${EndIf}
IntOp $R1 $R1 + 1
${LoopWhile} $R0 != ""
ClearErrors
Exch 2
Pop $R0
Pop $R1
Exch $R2
!macroend
Пример использования :
!insertmacro IfKeyExists "HKCU" "Software\Classes" ".MP3"
Pop $R0
;
${If} $R0 == "1"
MessageBox MB_OK "Ключ существует"
${ElseIf} $R0 == "0"
MessageBox MB_OK "Ключ не существует"
${EndIf}
Не сложный макрос для проверки ключа реестра на наличие: »
А разве классическая проверка не работает ? :
ClearErrors
EnumRegKey $0 HKCR "SOFTWARE\Test" 0
IfErrors 0 keyexist
# key does not exist
keyexist:
или
ClearErrors
ReadRegStr $0 HKLM "SOFTWARE\Test" ""
${If} ${Errors}
; или , в зависимости от ситуации, используем ${If} $0 == ""
# key does not exist
${EndIf}
а для более "расширенных" случаев, лучше использовать Registry plug-in http://nsis.sourceforge.net/Registry_plug-in
KeyExists (check if registry key exists)
${registry::KeyExists} "[fullpath]" $var
может кому пригодится - конвертация размера файла из KB в MB :
OutFile "Size_test.exe"
Var InSize
Var OutSize
Section
;задаём размер в KB, который надо конвертировать
;StrCpy $InSize 1024
StrCpy $InSize 2048
StrCpy $1 $InSize
IntCmp $1 1024 +3 +1 +3
StrCpy $1 "$1.0KB"
Goto +12
IntOp $1 $1 * 100
IntOp $1 $1 / 1024
StrCpy $2 $1 "" -1
StrCpy $3 $1 1 -2
StrCpy $1 $1 -2
IntCmp $2 5 +1 +2 +1
IntOp $3 $3 + 1
StrCmp $3 10 +1 +3
StrCpy $3 0
IntOp $1 $1 + 1
StrCpy $1 "$1.$3 MB"
StrCpy $OutSize $1
MessageBox MB_ICONINFORMATION|MB_OK '$InSize KB = $OutSize'
SectionEnd
Пользовательские иконки из DLL - в MessageBox
Уже был макрос для этого , но можно использовать и такой вариант :
outfile MessageBoxIco_test.exe
!define MSGBOXPARAMS '(i, i, i, t, t, i, t, i, i, i) i'
!define ID_ICO 16
Section
System::Call 'Kernel32::LoadLibrary(t "Fileicons.dll") i .r1'
IntCmp $1 0 Err Err 0
System::Call '*${MSGBOXPARAMS}(40, $HWNDPARENT, r1, "Текст сообщения", " Заголовок", 0x80|0x0, i ${ID_ICO}, 0, 0, 0) .r3'
System::Call 'User32::MessageBoxIndirect(i r3) v r4'
System::Call 'Kernel32::FreeLibrary(i r1) v r4'
System::Free $3
Err:
SectionEnd
; Кнопки и надписи действий на кнопках
; 0x0 - ОК
; 0x1 - ОК Отмена
; 0x2 - Прервать Повтор Пропустить
; 0x3 - Да Нет Отмена
; 0x4 - Да Нет
; 0x5 - Повтор Отмена
; 0x6 - Отмена Повторить Продолжить
; 0x4000 - ОК Справка
Fileicons.dll - это в примере, библиотека из TotalCommander_a. Ессно можно использовать любую DLL. ( Не забываем организовать путь к библиотеке. Из $PLUGINSDIR или как угодно )
Номер ID_ICO необходимой иконки из DLL - смотрим в любом редакторе ресурсов.
Kopejkin
16-03-2014, 15:10
Есть такой плагин WPatch (http://nsis.sourceforge.net/WPatch_plug-in)
Вместе с ним идет пример сценария.
; WPatch - Sample script
!system "rmdir /s /Q dir_to_patch"
!system "xcopy /E /Q /H dir1\* dir_to_patch\"
!ifdef TARGETDIR
!addplugindir "${TARGETDIR}"
!else
!addplugindir "..\..\bin"
!endif
Name "Sample WPatch"
OutFile Sample.exe
ShowInstDetails show
InstallDir $EXEDIR\dir_to_patch
Page directory
Page instfiles
Section
InitPluginsDir
SectionEnd
!include WGenPatDir.nsh
Section
IfErrors 0 +2
MessageBox MB_OK "There has been some errors !"
SectionEnd
Вопрос по выделенным красным строках (для общего развития)
В примере также имеются папки с файлами dir1 и dir2. Соответственно, первая - с исходными файлами и папками, вторая - с измененными.
После запуске батника создается файл отличий *.pat и WGenPatDir.nsh, который в дальнейшем будет использоваться для пропатчивания.
Если я правильно понял вторую строку, то содержимое папки dir1 должно скопироваться в папку dir_to_patch во время компиляции сценария?
Созданный патч Sample.exe после запуска "натравливается" на содержимое этой папки dir_to_patch.
В реальности, папка dir_to_patch удаляется, а такая же, с исходным содержимым папки dir1, не появляется. В чем прикол?
В русскоязычном Руководстве о параметрах команды !system написано не очень много и не совсем по-русски.
Практически же, я в InstallDir прописываю путь к нужной мне (исходной) папке, содержимое которой дублируется в папке dir1 для создания данных патча , а выделенные красным строки игнорирую, как комментарий.
kotkovets
17-03-2014, 15:29
!system написано не очень много и не совсем по-русски. »
! - с этого символа: это команды компилятора.
!system - компилятор задействует системные ресурсы (приложения)
!system "rmdir /s /Q dir_to_patch"
!system "xcopy /E /Q /H dir1\* dir_to_patch\"
1 перед компиляцией удаляется каталог dir_to_patch относительно скрипта
2 копируется содержимое каталога dir1 в каталог dir_to_patch
(этот каталог создается заново, для того, что бы не попали в проект файлы предыдущей компиляции)
В реальности, папка dir_to_patch удаляется, а такая же, с исходным содержимым папки dir1, не появляется. В чем прикол? »
посмотрите ключи системной утилиты xcopy
Kopejkin
21-03-2014, 15:42
Используя в сценарии этот код
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}_Localize"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
SetShellVarContext all
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Удалить русификатор ${PRODUCT_NAME}.lnk" "$INSTDIR\unrus.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}${PRODUCT_VERSION}. Удалить русификатор"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\unrus.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "1.0"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "©Kopejkin, 03/2014"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\unrus.exe"
WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "NoModify" 0x00000001
На Windows 8 я получаю ярлыки в Панели управления
http://savepic.su/4233661m.png (http://savepic.su/4233661.htm)
и, как бы, в меню Пуск.
http://savepic.su/4227517m.png (http://savepic.su/4227517.htm)
А ярлыков не видно ни здесь
http://savepic.su/4235709m.png (http://savepic.su/4235709.htm)
ни здесь
http://savepic.su/4240829m.png (http://savepic.su/4240829.htm)
На Win7 ярлык нормально отображается в меню Пуск. Как правильно написать и для Win 8?
Разрядность ОС - только х64
Kopejkin, если во всем сценарии нет ошибок, то все ярлыки будут созданы согласно указанным командам. По крайней мере у себя я таких проблем не наблюдаю (пользуюсь NSIS v3.0a2). Вот проверил на виртуалке:
http://savepic.org/5148279m.png (http://savepic.org/5148279.htm)
Kopejkin
22-03-2014, 03:51
Flix, поделитесь этим тестовым сценарием, пожалуйста. Попробую сам разобраться, а для этого потребуется 100% рабочий.
поделитесь этим тестовым сценарием »
Kopejkin, да делиться нечем. Загляните в папку "Examples" по месту установки NSIS. В частности, при тестировании я использовал сценарий WelcomeFinish.nsi из папки "Modern UI". Я только добавил команды создания ярлыков в секцию "Dummy Section":
CreateDirectory "$SMPROGRAMS\МОЯ ПРОГРАММА"
CreateShortCut "$SMPROGRAMS\МОЯ ПРОГРАММА\УДАЛИТЬ_ТЕСТ.lnk" "$INSTDIR\Uninstall.exe"
И в секцию "Uninstall" их удаление
Delete "$SMPROGRAMS\МОЯ ПРОГРАММА\УДАЛИТЬ_ТЕСТ.lnk"
RMDir "$SMPROGRAMS\МОЯ ПРОГРАММА"
Потом сделал копию файла WelcomeFinish.nsi, переименовал его в WelcomeFinish_rus.nsi (имитация русификатора) и соответственно изменил в нём название файла деинсталляции (Uninstall_rus.exe) и имя ярлыка (УДАЛИТЬ_RUS.lnk). На этом все.
Kopejkin
23-03-2014, 14:35
Добиться отображения ярлыков и в Приложениях и в Установке/Удалении на Win8 мне не удается.
Отключаю блок Установка/Удаление - ярлык "Удалить русификатор..." отображается в Приложениях.
Включаю - ярлык "Удалить русификатор..." в папке с ярлыками программы присутствует, а Приложениях - не отображается.
Может я что-то упускаю, подскажите, пожалуйста.
Тренируюсь на этом сценарии:
########## ПРИМЕР ##############
!define PRODUCT_NAME "FolderSizes 7"
!define PRODUCT_VERSION ".0.56"
!define BRANDING "PUPKIN"
!include "MUI.nsh"
SetCompressor /SOLID lzma
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "Russian"
Name "${PRODUCT_NAME}"
Caption "Установка русификатора ${PRODUCT_NAME}${PRODUCT_VERSION}"
UninstallCaption "Удаление русификатора ${PRODUCT_NAME}${PRODUCT_VERSION}"
OutFile "rus.${PRODUCT_NAME}${PRODUCT_VERSION}.exe"
InstallDir "$PROGRAMFILES64\Key Metric Software\${PRODUCT_NAME}"
RequestExecutionLevel admin
ShowInstDetails show
ShowUninstDetails show
BrandingText "${BRANDING}"
Section "-MainSection"
SetOutPath "$INSTDIR"
File /r "D:\Example1\1.txt"
WriteUninstaller "$INSTDIR\unrus.exe"
/*
; блок Установка/Удаление программм
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "DisplayName" "${PRODUCT_NAME}${PRODUCT_VERSION}. Удалить русификатор"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "UninstallString" "$INSTDIR\unrus.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "DisplayVersion" "1.0"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "Publisher" "© Pupkin, 03/2014"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "DisplayIcon" "$INSTDIR\unrus.exe"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "NoModify" 0x00000001
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "NoRepair" 0x00000001
*/
SetShellVarContext all
; Ярлыки в меню Пуск - Программы
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
; в Win8 этот ярлык виден в ПРИЛОЖЕНИЯХ в ЛЮБОМ случае
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Открыть 1.txt.lnk" "$INSTDIR\1.txt"
; в Win8 этот ярлык виден в ПРИЛОЖЕНИЯХ только при "ОТКЛЮЧЕНИИ" блока "Установка/Удаление"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Удалить русификатор ${PRODUCT_NAME}.lnk" "$INSTDIR\unrus.exe"
SetAutoClose false
SectionEnd
Section Uninstall
Delete "$INSTDIR\1.txt"
SetShellVarContext all
Delete "$SMPROGRAMS\${PRODUCT_NAME}\Открыть 1.txt.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\Удалить русификатор ${PRODUCT_NAME}.lnk"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus"
delete "$INSTDIR\unrus.exe"
SetAutoClose false
SectionEnd
Kopejkin, вы в своем сценарии не учли особенности систем 64-бит. Помимо раздельных каталогов для установки 32-бит и 64-бит приложений ("Program Files (x86)" и "Program Files" соответственно), 64-бит версии Windows поддерживают два разных представления реестра - 32-бит и 64-бит (для 32-бит приложений работает WOW64). Короче, в своем сценарии, установку деинсталлятора вы осуществляете в каталог для 64-бит приложений, а запись о деинсталляции выполняете в 32-бит ветку реестра. В итоге ярлык деинсталляции получается битый и Windows разумно полагает, что ему не место на экране Приложений, и не показывает его. По умолчанию NSIS создает инсталлятор для установки 32-бит приложений. Если требуется установка приложения с учетом 64-бит архитектуры, то в сценарии нужно предусмотреть эти моменты и дать соответствующие команды. В данном случае, при записи в реестр, нужно установить доступ к 64-бит ветке реестра. Делается это командой SetRegView (почитайте про неё в справке NSIS).
Поэтому, перед командами записи данных в реестр, укажите команду SetRegView 64. Аналогично и для секции деинсталляции, чтобы корректно удалить записанные ключи.
########## ПРИМЕР ##############
!define PRODUCT_NAME "FolderSizes 7"
!define PRODUCT_VERSION ".0.56"
!define BRANDING "PUPKIN"
!include "MUI.nsh"
SetCompressor /SOLID lzma
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "Russian"
Name "${PRODUCT_NAME}"
Caption "Установка русификатора ${PRODUCT_NAME}${PRODUCT_VERSION}"
UninstallCaption "Удаление русификатора ${PRODUCT_NAME}${PRODUCT_VERSION}"
OutFile "rus.${PRODUCT_NAME}${PRODUCT_VERSION}_with_reg.exe"
; Установка в каталог для 64-бит приложений!
InstallDir "$PROGRAMFILES64\Key Metric Software\${PRODUCT_NAME}"
RequestExecutionLevel admin
ShowInstDetails show
ShowUninstDetails show
BrandingText "${BRANDING}"
Section "-MainSection"
SetOutPath "$INSTDIR"
File /r "1.txt"
WriteUninstaller "$INSTDIR\unrus.exe"
; Устанавливаем доступ к 64-бит ветке реестра
SetRegView 64
; блок Установка/Удаление программм
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "DisplayName" "${PRODUCT_NAME}${PRODUCT_VERSION}. Удалить русификатор"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "UninstallString" "$INSTDIR\unrus.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "DisplayVersion" "1.0"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "Publisher" "© Pupkin, 03/2014"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "DisplayIcon" "$INSTDIR\unrus.exe"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "NoModify" 0x00000001
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus" "NoRepair" 0x00000001
SetShellVarContext all
; Ярлыки в меню Пуск - Программы
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
; в Win8 этот ярлык виден в ПРИЛОЖЕНИЯХ в ЛЮБОМ случае
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Открыть 1.txt.lnk" "$INSTDIR\1.txt"
; в Win8 этот ярлык виден в ПРИЛОЖЕНИЯХ только при "ОТКЛЮЧЕНИИ" блока "Установка/Удаление"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Удалить русификатор ${PRODUCT_NAME}.lnk" "$INSTDIR\unrus.exe"
SetAutoClose false
SectionEnd
Section Uninstall
Delete "$INSTDIR\1.txt"
SetShellVarContext all
Delete "$SMPROGRAMS\${PRODUCT_NAME}\Открыть 1.txt.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\Удалить русификатор ${PRODUCT_NAME}.lnk"
; Устанавливаем доступ к 64-бит ветке реестра
SetRegView 64
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}rus"
Delete "$INSTDIR\unrus.exe"
SetAutoClose false
SectionEnd
Еще подумайте, что произойдет, если пользователь запустит ваш инсталлятор на 32-бит системе. Полагаю, что необходимо выполнять проверку битности и соответственно ей выполнять те или иные команды установки.
Kopejkin
24-03-2014, 02:18
Flix, спасибо за ответ, но так... тоже не работает.
Если устанавливать в C:\Program Files (x86), все происходит точно также: ярлык деинсталлятора отображается в Приложениях только после "скрытия" блока Установки/Удаления. :blink:
Цитата Flix:
Еще подумайте..»
Как раз с этим проблем не было. K.A.V. подсказочку подарил, правда по другому поводу...
Function .OnInit
var /global IsWow64Process
System::Call kernel32::GetCurrentProcess()i.s
System::Call kernel32::IsWow64Process(is,*i.s)
Pop $IsWow64Process
StrCmp $IsWow64Process "1" +3 0
MessageBox MB_OK|MB_ICONSTOP "Только для х64!" IDOK
Quit
FunctionEnd
erd-zelen
24-03-2014, 11:20
как в NSIS создать проект *.exe имея архив 7z, иконку, бантик, файл txt с настройками для sfx. Обычно делал до этого кнопкой (button), небольшие репаки прог и портабле.
Может есть какой то инструмент чтобы с нуля скрипт не писать (я этого делать не умею), а потом только вписать правельные название файлов, версия...
kotkovets
24-03-2014, 11:29
Может есть какой то инструмент чтобы с нуля скрипт не писать (я этого делать не умею) »
учитесь писать..
простенькое IDE встроен в nisedit2.0.3 (http://hmne.sourceforge.net/) проект давно не развивался, но простых задач сойдет.
erd-zelen
24-03-2014, 11:35
простенькое IDE встроен в nisedit2.0.3 »
там не работает создание проекта мастером, локацию просит указать а курсор туда не переводится.
http://i57.fastpic.ru/big/2014/0324/08/ef04999d4f7cbb0e88b605d76221f108.jpg (http://i33.fastpic.ru/big/2014/0324/83/97bffe508bbeb00f2ba1c607e8724383.jpg)
kotkovets
24-03-2014, 11:50
там не работает создание проекта мастером, локацию просит указать а курсор туда не переводится »
сделайте редактор по умолчанию --> F11, установите NSIS, если не установлен .. O_o
erd-zelen
24-03-2014, 11:54
сделал, не помогло. ось хр стоит. не пойму как язык туда прикрутить чтобы не ругался.
kotkovets
24-03-2014, 12:01
сделал, не помогло. ось хр стоит. не пойму как »
Справочник по NSIS русски в шапке темы - обязательно к чтению и изучению
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC