Ru-Board.club
← Вернуться в раздел «Программы»

» NSIS (Nullsoft Scriptable Install System)

Автор: Victor_VG
Дата сообщения: 18.05.2014 19:57
FanIT

Правильно, сначала надо в инклюде подключить его хидеры. Но, лучше воспользоваться NsProcess. Пишем в хидере скрипта:

!include nsProcess.nsh

а после ${nsProcess::CloseProcess} "process.exe" $R0

выгрузка либы ${NsProcess::Unload}
Автор: FanIT
Дата сообщения: 18.05.2014 20:38
Victor_VG
Конечно я подключил в инклюдах. Это само собой. nsProcess я использовал. Но мне надо, чтобы сначала выгрузился процесс, а уж потом удалялась папка. А в ProcessFunc есть функция ProcessWait. Или в nsProcess есть что-то подобное?
Автор: Victor_VG
Дата сообщения: 18.05.2014 20:56
FanIT

Есть, и есть проверка результатов вызова. Прочтите его описание, особенно для версии 1.6.
Автор: FanIT
Дата сообщения: 18.05.2014 21:35
Victor_VG
Спасибо понял!
Автор: Victor_VG
Дата сообщения: 19.05.2014 01:03
FanIT

Не за что. Код проверки результатов возврата есть в моей ProcLib (в Update для NSIS 2.46). Если что - перекину когда с ремонтом закончу. Осталось самое сложное - водворить все машины на место и подключить кабели кластера. Сменить сгоревший БП дело пяти минут.
Автор: 0utC4St
Дата сообщения: 23.05.2014 21:54
Кто скажет в чём подвох и как выйти из ситуации стандартными средствами?
Исходим из того, что в реестре в этом месте ЕСТЬ строка вида: C:\Program Files\WinRAR\

Код: ...
RequestExecutionLevel admin

Function .onInit
var /Global Path
StrCpy $Path ""
FunctionEnd

Section "Main"
    ReadRegStr $Path HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver" "InstallLocation"
    MessageBox MB_OK|MB_ICONSTOP "$Path"
SectionEnd
Автор: Victor_VG
Дата сообщения: 23.05.2014 22:47
0utC4St

Есть такой хитрый подвох и он связан с виртуализацией Реестра. Тут лучше использовать встроенные в NSIS инструменты - определить в хидере $InstallDirRegKey и через неё читать значение. У меня сейчас нет под руками х64 винды и экспериментально я проверить код не могу, но про сию бяку я знаю.
Автор: 0utC4St
Дата сообщения: 23.05.2014 23:41
Victor_VG,
// В примере реальный ключ установленного WinRAR


Код:
Name "myprog"
OutFile "myprog.exe"
RequestExecutionLevel admin
SilentInstall silent

InstallDirRegKey "HKLM" "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver" "InstallLocation"

Section
MessageBox MB_OK "$INSTDIR"
SectionEnd
Автор: Victor_VG
Дата сообщения: 23.05.2014 23:56
0utC4St

Так дефайны-то не определены. Вот [more=пример скрипта сгененрированного HM NIS 2.0.3]; Script generated by the HM NIS Edit Script Wizard.

; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "Моя программа"
!define PRODUCT_VERSION "1.0"
!define PRODUCT_PUBLISHER "Моя компания, LLC."
!define PRODUCT_WEB_SITE "http://www.mycompany.com"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\AppMainExe.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"

; MUI 1.67 compatible ------
!include "MUI.nsh"

; MUI Settings
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"

; Welcome page
!insertmacro MUI_PAGE_WELCOME
; License page
!insertmacro MUI_PAGE_LICENSE "c:\path\to\licence\YourSoftwareLicence.txt"
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_FINISHPAGE_RUN "$INSTDIR\AppMainExe.exe"
!insertmacro MUI_PAGE_FINISH

; Uninstaller pages
!insertmacro MUI_UNPAGE_INSTFILES

; Language files
!insertmacro MUI_LANGUAGE "Russian"

; MUI end ------

Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "setup.exe"
InstallDir "$PROGRAMFILES\Моя программа"
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails show
ShowUnInstDetails show

Section "Main" SEC01
SetOutPath "$INSTDIR"
SetOverwrite ifnewer
File "c:\path\to\file\AppMainExe.exe"
CreateDirectory "$SMPROGRAMS\Моя программа"
CreateShortCut "$SMPROGRAMS\Моя программа\Моя программа.lnk" "$INSTDIR\AppMainExe.exe"
CreateShortCut "$DESKTOP\Моя программа.lnk" "$INSTDIR\AppMainExe.exe"
File "c:\path\to\file\Example.file"
SectionEnd

Section -AdditionalIcons
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
CreateShortCut "$SMPROGRAMS\Моя программа\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
CreateShortCut "$SMPROGRAMS\Моя программа\Uninstall.lnk" "$INSTDIR\uninst.exe"
SectionEnd

Section -Post
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\AppMainExe.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\AppMainExe.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
SectionEnd


Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "Удаление программы $(^Name) было успешно завершено."
FunctionEnd

Function un.onInit
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Вы уверены в том, что желаете удалить $(^Name) и все компоненты программы?" IDYES +2
Abort
FunctionEnd

Section Uninstall
Delete "$INSTDIR\${PRODUCT_NAME}.url"
Delete "$INSTDIR\uninst.exe"
Delete "$INSTDIR\Example.file"
Delete "$INSTDIR\AppMainExe.exe"

Delete "$SMPROGRAMS\Моя программа\Uninstall.lnk"
Delete "$SMPROGRAMS\Моя программа\Website.lnk"
Delete "$DESKTOP\Моя программа.lnk"
Delete "$SMPROGRAMS\Моя программа\Моя программа.lnk"

RMDir "$SMPROGRAMS\Моя программа"
RMDir "$INSTDIR"

DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
SetAutoClose true
SectionEnd[/more] и там мы видим что определены три переменных:

!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\AppMainExe.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"

которые стуб использует для поиска пути в Реестре. Если их нет он может что угодно оттуда прочитать, т.е. мусор. Что мы и видим.
Автор: 0utC4St
Дата сообщения: 24.05.2014 00:11
Victor_VG,
[more=Исправил]
Код:
!define ROOT_KEY "HKLM"
!define SUBKEY "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver"
!define KEY_NAME "InstallLocation"

Name "myprog"
OutFile "myprog.exe"
RequestExecutionLevel admin
SilentInstall silent

InstallDirRegKey ${ROOT_KEY} "${SUBKEY}" "${KEY_NAME}"

Section
MessageBox MB_OK "$INSTDIR"
SectionEnd
Автор: Victor_VG
Дата сообщения: 24.05.2014 00:27
0utC4St

Стоп, стоп, это я уже сплю. Это штука работать-то не должна ибо если заглянуть в справку там записано:

Language strings and variables cannot be used with InstallDirRegKey.

- т.е. в данном операторе нужно прямо указывать путь в Реестре без каких либо переменных, а потому просто пишем оператор:

InstallDirRegKey "HKLM" "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver" "InstallLocation"

так значение считается правильно.
Автор: 0utC4St
Дата сообщения: 24.05.2014 00:36
Victor_VG, весь код ваш и мой работает верно, НО только на x86
Автор: Victor_VG
Дата сообщения: 24.05.2014 00:39
0utC4St

Тогда надо использовать х64 редакцию NSIS чтобы уйти от виртуализации.
Автор: 0utC4St
Дата сообщения: 24.05.2014 00:55
При использовании NSIS x64 код работает, но, естественно, только на x64

Господа, кто в курсе как штатными средствами "уйти от вирутализации" (см. последнии 8-9 сообщений темы)?
Автор: Victor_VG
Дата сообщения: 24.05.2014 01:37
0utC4St

Можно, конечно, но придётся использовать логику определения платформы в .onInit и уже там менять $INSTDIR. Я похожие номера когда-то проделывал с помощью плагина GetVersion, но он не будет работать на восьмёрке и выше. Придётся прикинуть варианты.
Автор: MKN
Дата сообщения: 24.05.2014 09:40
0utC4St

Цитата:
как выйти из ситуации стандартными средствами?

Всё давно придумано и вся сеть завалена примерами...
Надо использовать хедер x64.nsh
И при необходимости логику для $INSTDIR Т.е. -
${If} ${RunningX64}
бла-бла
Автор: leserg73
Дата сообщения: 24.05.2014 10:27
Есть еще команда SetRegView для переключения операций в реестре 64-бит или 32-бит. Также можно использовать совместно хедером x64.nsh...
${If} ${RunningX64}
SetRegView 64
бла-бла
${Else}
SetRegView 32
бла-бла
${EndIf}
Автор: 0utC4St
Дата сообщения: 24.05.2014 10:45
MKN, leserg73
Спасибо! Вы абсолютно правы, для унификации кода достаточно этого:

Код:
!include "x64.nsh"
!include "LogicLib.nsh"

Function .onInit
${If} ${RunningX64}
SetRegView 64
${Else}
SetRegView 32
${EndIf}
FunctionEnd
Автор: FanIT
Дата сообщения: 29.05.2014 20:54
Всем привет. Использую код из руководства для определение SID текущего пользователя, но возвращается пустое значение.
Вот код:

!define GetUserSID "!insertmacro CallGetUserSID"
!macro CallGetUserSID USERNAME SID
System::Store S
StrCpy '$0' '${USERNAME}'
StrCmp '$0' '' 0 +2
ExpandEnvStrings '$0' "%USERNAME%"
System::Call "*(&t1024)i.r1"
System::Call "advapi32::LookupAccountName(tn,tr0,ir1,*i1024,tn,*i1024,*in)i.r0"
IntCmp $0 1 0 +2 +2
System::Call "advapi32::ConvertSidToStringSid(ir1,*t.s)"
IntCmp $0 1 +2 0 0
Push error
System::Free $1
System::Store L
Pop "$R1"
!macroend

Мой код вызова:

${GetUserSID} "" $R7

Что я опять не так делаю?
Автор: Victor_VG
Дата сообщения: 29.05.2014 21:05
FanIT

Параметр макроса не может быть пустым, а у вас в вызове в макрос (по факту это подпрограмма) передаётся пустое значение $USERNAME, а потому и результат предсказуем - такого пользователя в системе нет.
Автор: MKN
Дата сообщения: 29.05.2014 22:04
FanIT
это известный код из справочника :

Цитата:
!include "MUI2.nsh"

!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"

ShowInstDetails show
OutFile GetUserSID-Test.exe
Caption "GetUserSID"

!define GetUserSID "!insertmacro CallGetUserSID"
!macro CallGetUserSID SID
System::Store S
System::Call "kernel32::GetComputerName(t.r0, *i1024 r4)i.r2"
System::Call "advapi32::GetUserName(t.r1, *i1024 r5)i.r3"
${Unless} $2 = 0
${AndUnless} $3 = 0
System::Call "*(&t1024)i.r5"
System::Call "advapi32::LookupAccountName(t'\\$0',tr1,ir5,*i1024,t.r4,*i1024,*i.r0)i.r2"
${Unless} $2 = 0
System::Call "advapi32::ConvertSidToStringSid(ir5,*t.s)"
${Else}
Push error
${EndUnless}
${Else}
Push error
${EndUnless}
System::Store L
Pop "${SID}"
!macroend

Section
${GetUserSID} $R5
MessageBox MB_ICONINFORMATION|MB_OK "$R5" IDOK
SectionEnd

Автор: FanIT
Дата сообщения: 29.05.2014 22:54
Victor_VG
Так в справочники написано. Если передается пустое значение, то возвращается sid текущего пользователя. Что мне собственно и нужно.

MKN
Я его оттуда и взял.
Автор: Victor_VG
Дата сообщения: 30.05.2014 00:34
FanIT

я же вам сразу сказал что параметр USERNAME не может быть пустым.

Цитата:
ShowInstDetails show
OutFile GetUserSID-Test.exe
Caption "GetUserSID"

!define GetUserSID "!insertmacro CallGetUserSID"
!macro CallGetUserSID USERNAME SID NAME
System::Store S
StrCpy $0 "${USERNAME}"
StrCpy ${NAME} $0
StrCmp $0 "" +2
ReadEnvStr $0 USERNAME
System::Call "*(&t1024)i.r1"
System::Call "advapi32::LookupAccountName(tn,tr0,ir1,*i1024,tn,*i1024,*in)i.r0"
IntCmp $0 1 0 +2 +2
System::Call "advapi32::ConvertSidToStringSid(ir1,*t.s)"
IntCmp $0 1 +2 0 0
Push error
System::Free $1
System::Store L
Pop ${SID}
!macroend

Section
${GetUserSID} "" $R5 $R2
MessageBox MB_ICONINFORMATION|MB_OK "User is: $R2 $\nSID is: $R5" IDOK
SetAutoClose true
SectionEnd

я тут лишнее прибрал, ну и поправил ошибки в коде. Так работает, попробуйте найти и объяснить нам свои ошибки.

P.S.

MKN - не подсказывай, FanIT надо понять как это работает, тогда эти знания станут его, а иначе вся работа насмарку...
Автор: FanIT
Дата сообщения: 30.05.2014 17:32
Victor_VG
MKN
Спасибо вам! Теперь понял.


Код:
!define GetUserSID "!insertmacro CallGetUserSID"
!macro CallGetUserSID USERNAME SID
System::Store S
StrCpy $0 "${USERNAME}"
StrCmp $0 "" +2
ReadEnvStr $0 USERNAME
System::Call "*(&t1024)i.r1"
System::Call "advapi32::LookupAccountName(tn,tr0,ir1,*i1024,tn,*i1024,*in)i.r0"
IntCmp $0 1 0 +2 +2
System::Call "advapi32::ConvertSidToStringSid(ir1,*t.s)"
IntCmp $0 1 +2 0 0
Push error
System::Free $1
System::Store L
Pop ${SID}
!macroend

ExpandEnvStrings $R4 "%USERNAME%"

${GetUserSID} $R4 $R5
Автор: Victor_VG
Дата сообщения: 30.05.2014 17:38
FanIT

Поняли в чём были ошибки? Хорошо.
Автор: FanIT
Дата сообщения: 05.06.2014 20:17
Всем привет! Не подскажите. Есть какой-нибудь аналог утилите reg2nsis? Она почему-то конвертирует только часть ключей реестра из reg файла.
Автор: Victor_VG
Дата сообщения: 05.06.2014 20:41
FanIT

Смотря какая версия. Утилита да, не идеальна, но пользоваться можно. Последняя её версия у автора Reg2Nsis v0.14, новее не видел...
Автор: FanIT
Дата сообщения: 05.06.2014 21:50
Victor_VG
Версия последняя. Почему-то стала только половину конвертировать. Хорошо вовремя заметил. Ясно будем думать.
Автор: Victor_VG
Дата сообщения: 05.06.2014 22:19
FanIT

Дак она и раньше не всё брала. Вечно после неё надо руками править. Это известный глюк, пишите автору, может поправит коли у него её исходники сохранились...
Автор: FanIT
Дата сообщения: 05.06.2014 22:29
Victor_VG
Раньше проблем вроде не было. Наверно везло.

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364

Предыдущая тема: The Bat!


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.