Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
kotkovets
09-11-2013, 19:53
Моя интуиция подсказывает, что эти две, правильно ? »
альтернативы не существует :biggrin:
как-то можно сгенерировать случайное число ? »
http://nsis.sourceforge.net/NsRandom_plug-in
http://nsis.sourceforge.net/Rnd
http://nsis.sourceforge.net/Random
А также:
System::Call kernel32::GetTickCount()i.r1
IntOp $1 $1 % 10
Mafia_forever
10-11-2013, 13:40
Всем привет , у меня есть вопрос ! Можно ли разбить на тома инсталлятор как в Inno Setup ?
Kopejkin
10-11-2013, 13:42
Делаю патчер с проверкой MD5 файла. При каких-либо отличиях выводятся свои сообщения. При наличии измененного этим патчем файла (сооб.1) и при несоответствии оригинального файла (сооб.2). Возврат к поиску другой папки после Сооб.2 оправдан. А вот после Сооб.1 приходится выполнять лишнее действие. Даже два, так как приходится щелкать еще и в окне запроса подтверждения отмены установки.
Можно ли закрыть программу инсталляции сразу после вывода сообщения 1, а не возвращаться для отдельной отмены установки?
!include "MUI2.nsh"
!include "VPatchLib.nsh"
!include "Logiclib.nsh"
!include "ProcessFunc.nsh"
SetCompressor /SOLID lzma
!define PRODUCT_NAME "Screenshot Captor"
!define PRODUCT_VERSION "4.7.2"
!define pkgdir "d:\pr_ScreenshotCaptor.472"
!define BRANDING "©KOPEJKIN, 10/2013"
!define MUI_ABORTWARNING
!define MUI_ABORTWARNING_TEXT "Отменить установку русификатора ${PRODUCT_NAME} ${PRODUCT_VERSION}?"
!define MUI_WELCOMEFINISHPAGE_BITMAP "${pkgdir}\res\logo.bmp"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "${pkgdir}\res\top_rus_inst_r.bmp"
!define MUI_HEADERIMAGE_RIGHT
!insertmacro MUI_PAGE_LICENSE "lic_rus.rtf"
!define MUI_PAGE_HEADER_TEXT "Информация"
!define MUI_LICENSEPAGE_TEXT_BOTTOM " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "
!define MUI_LICENSEPAGE_BUTTON "Далее"
!insertmacro MUI_PAGE_LICENSE "ug_rus.rtf"
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE Check
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "Russian"
Caption "Русификация ${PRODUCT_NAME} ${PRODUCT_VERSION}"
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
BrandingText "${BRANDING}"
InstallDir ""
OutFile "sc472rus.kopejkin.exe"
RequestExecutionLevel admin
ShowInstDetails show
ShowUninstDetails show
Section "-Русификатор"
SetOutPath $INSTDIR
CreateDirectory "$INSTDIR\Backup"
CopyFiles /SILENT $INSTDIR\ScreenshotCaptor.exe $INSTDIR\Backup\ScreenshotCaptor.exe.bak
DetailPrint "Подготовка к изменению файла ScreenshotCaptor.exe..."
!insertmacro VPatchFile "sc472rus.pat" "$INSTDIR\ScreenshotCaptor.exe" "$INSTDIR\temporaryfile.exe"
SectionEnd
Function .OnInit
${KillProcess} "ScreenshotCaptor.exe" $0
FunctionEnd
Function .onVerifyInstDir
IfFileExists "$INSTDIR\ScreenshotCaptor.exe" PathGood
Abort
PathGood:
FunctionEnd
Function Check
StrCpy $0 "$INSTDIR\ScreenshotCaptor.exe"
md5dll::GetMD5File "$0"
Pop $1
StrCpy $R1 $1
${If} $R1 == 2422E63F23D86C754C5CB9606196D036
${ElseIf} $R1 == 5755a1c31f67191f0fbcaa9548c48e8e
MessageBox MB_OK|MB_DEFBUTTON2|MB_ICONINFORMATION "\
РУССКАЯ версия УЖЕ установлена на этом компьютере.$\n$\n\
Нажмите кнопку 'OK' для закрытия этого сообщения$\n\
и ОТМЕНИТЕ установку данного русификатора." IDOK
Quit ; Здесь применяем команду Quit, а не Abort. Тогда после нажатия кнопки ОК программа установки будет закрыта .
${Else}
MessageBox MB_OK|MB_ICONSTOP| "Здесь - ($INSTDIR),$\n\
находится файл программы, для изменения которого$\n\
данный русификатор НЕ ПРЕДНАЗНАЧЕН!$\n$\n\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$\n\
Возможные причины: $\n\
- выбрана неверная папка ${PRODUCT_NAME} ${PRODUCT_VERSION};$\n\
- программа ${PRODUCT_NAME} ${PRODUCT_VERSION} не установлена;$\n\
- попытка локализовать ${PRODUCT_NAME} другой версии;$\n\
- попытка локализовать измененный оригинальный файл.$\n$\n\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$\n$\n\
Нажмите 'OK' для выбора другой папки или ОТМЕНЫ установки." IDOK
Abort
${EndIf}
FunctionEnd
Спасибо, kotkovets! Исправил в коде, может еще кому пригодится.
kotkovets
10-11-2013, 15:36
Можно ли закрыть программу инсталляции сразу после вывода сообщения 1, а не возвращаться для отдельной отмены установки? »
прописать команду закрытия приложения: quit вместо прерывания аbort
Возможно ли в NSIS реализовать мониторинг создания ключей реестра, какой либо программой ?
Т.е. перехват обращений к реестру. Вроде как для этого есть функция CmRegisterCallback...
Вскользь про это было здесь : http://www.xakep.ru/magazine/xa/102/114/1.asp
kotkovets
11-11-2013, 14:24
Возможно ли в NSIS реализовать мониторинг создания ключей реестра, какой либо программой ? »
если кто-то напишет драйвер для NSIS..
А нужно ли это установщику?
А нужно ли это установщику? »
Появляется всё больше программ, "генерирующих" различные уникальные и не очень, ключи и данные в реестр (часто только при первом запуске ! ), которые после деинсталляции, как штатной, (так и организованной разработчиком NSIS дистрибутива) - не удаляются из реестра.
То что эти ключи и данные остаются в реестре - полбеды. В ряде случаев именно из-за их наличия, не возможно повторно установить программу, либо программа просто не станет работать...
Поэтому полная зачистка реестра от этой заразы, как перед установкой, так и при деинсталляции ПО, была бы очень полезна. Поэтому есть смысл мониторить образование таких ключей
если кто-то напишет драйвер для NSIS.»
Понятно, т.е. - этого не будет никогда...
Когда то рассматривался вопрос об использовании в качестве картинок - файлов формата Jpg
Есть код, позволяющий использовать Jpg и Gif файлы, а также изменять их размер :
!include MUI2.nsh
Page Custom mypage
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"
OutFile "Jpg-Resize-test.exe"
; Ссылка на идентификатор интерфейса, описывающий тип указателя интерфейса для возврата в ppvRet.
!ifndef IID_IPicture
!define IID_IPicture {7BF80980-BF32-101A-8BBB-00AA00300CAB}
!endif
!define SRCCOPY 0xCC0020
!define IMAGEPATH "$EXEDIR\Pict.jpg" ;
!define NEWSIZEW 300
!define NEWSIZEH 200
Function mypage
nsDialogs::Create 1044
Pop $0
System::Call 'oleaut32::OleLoadPicturePath(w "${IMAGEPATH}",i0r2,i0,i0,g"${IID_IPicture}",*i.r9)i.r1'
${If} $1 = 0
System::Call 'user32::GetDC(i0)i.s'
System::Call 'gdi32::CreateCompatibleDC(iss)i.r1'
System::Call 'gdi32::CreateCompatibleBitmap(iss,i${NEWSIZEW},i${NEWSIZEH})i.r2'
System::Call 'user32::ReleaseDC(i0,is)'
System::Call $9->3(*i.r3)i.r4 ; IPicture->get_Handle
${If} $4 = 0
System::Call 'gdi32::SetStretchBltMode(ir1,i4)'
System::Call '*(&i40,&i1024)i.r4' ; BITMAP / BITMAPINFO
System::Call 'gdi32::GetObject(ir3,i24,ir4)'
System::Call 'gdi32::SelectObject(ir1,ir2)i.s'
System::Call '*$4(i40,i.r6,i.r7,i0,i,i.s)' ; Grab size and bits-ptr AND init as BITMAPINFOHEADER
System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFOHEADER
System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFO
System::Call 'gdi32::StretchDIBits(ir1,i0,i0,i${NEWSIZEW},i${NEWSIZEH},i0,i0,ir6,ir7,is,ir4,i0,i${SRCCOPY})'
System::Call 'gdi32::SelectObject(ir1,is)'
System::Free $4
${EndIf}
System::Call 'gdi32::DeleteDC(ir1)'
System::Call $9->2() ; IPicture->release()
${EndIf}
${NSD_CreateBitmap} 1u 1u ${NEWSIZEW} ${NEWSIZEH} ""
Pop $9
;Not required when the control size matches: ${NSD_AddStyle} $9 ${SS_CENTERIMAGE}
SendMessage $9 ${STM_SETIMAGE} ${IMAGE_BITMAP} $2
nsDialogs::Show
System::Call 'gdi32::DeleteObject(ir2)'
FunctionEnd
Section
SectionEnd
При создании на стандартной финишной странице отмеченного чекбокса ( MUI_FINISHPAGE_RUN ), для запуска после установки (т.е. после закрытия PAGE_FINISH) чего либо ,
чтобы этого запуска не было, сначала надо снять отметку с чекбокса, а потом кликнуть Finish.
Иногда это не преемлемо и мешает управлению событиями...
Но на FINISHPAGE можно активировать кнопку "Cancel", нажатие которой, закроет страницу без запуска чего либо, даже если чекбокс отмечен.
OutFile "FinishCancelEnabled_test.exe"
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
#Do NOT use MUI_FINISHPAGE_CANCEL_ENABLED !
!define MUI_FINISHPAGE_RUN "$windir\explorer.exe"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW CancelEnabled
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
!ifndef SC_CLOSE
!define SC_CLOSE 0xF060
!endif
Function CancelEnabled
EnableWindow $mui.Button.Cancel 1
System::Call 'USER32::GetSystemMenu(i $hwndparent,i0)i.s'
System::Call 'USER32::EnableMenuItem(is,i${SC_CLOSE},i0)'
FunctionEnd
Section
SectionEnd
Не помню спрашивал или нет :unsure: Можно как-то упростить создание деинсталера, чтобы вручную не указать что, где нужно удалять ?
Можно как-то упростить создание деинсталера, чтобы вручную не указать что, где нужно удалять ? »
Есть uninstlog.nsh
http://nsis.sourceforge.net/Talk:Uninstall_only_installed_files
и
http://nsis.sourceforge.net/Advanced_Uninstall_Log_NSIS_Header
Но по моему, это не серьёзно... Годится только для частных случаев... Кто лучше самого создателя инсталлятора, может лучше знать что, как и когда удалять, условия и нюансы удаления ?
Но по моему, это не серьёзно... Годится только для частных случаев... Кто лучше самого создателя инсталлятора, может лучше знать что, как и когда удалять, условия и нюансы удаления ? »
Иногда нужно удалить файлы из папки, где до установки уже были файлы и после деинсталяции они не должны удаляться...в таких случаях очень неудобно вместо RMDIR /r целой папки, вручную писать команду удаления для каждого файла.
Автоматическая смена заголовка окна сообщений
Занятное решение...
OutFile "MB_Title.exe"
!include "WinMessages.nsh"
!define InstCaption "Обычный заголовок"
!define MBCaption1 "А сейчас - необычный !"
!define MBCaption2 "Во как !"
Caption "${InstCaption}"
Function .onInit
# If you don't want the blinking caption on the taskbar as well, use .onGUIInit
InitPluginsDir
WriteUninstaller $PLUGINSDIR\MBCaption.exe
MessageBox MB_OK|MB_ICONINFORMATION|MB_TOPMOST "Обычный заголовок"
Exec "$PLUGINSDIR\MBCaption.exe"
MessageBox MB_OK|MB_USERICON|MB_TOPMOST "А сейчас - необычный !"
MessageBox MB_OK|MB_ICONINFORMATION|MB_TOPMOST "Снова обычный заголовок"
Abort
FunctionEnd
Section "Blank"
SectionEnd
Function un.onInit
FindWindow $0 "" "${InstCaption}" "" ""
IsWindow $0 0 -1
CaptionLoop:
SendMessage $0 ${WM_SETTEXT} "0" "STR:${MBCaption1}"
Sleep 800
SendMessage $0 ${WM_SETTEXT} "0" "STR:"
Sleep 400
SendMessage $0 ${WM_SETTEXT} "0" "STR:${MBCaption2}"
Sleep 800
SendMessage $0 ${WM_SETTEXT} "0" "STR:"
Sleep 400
FindWindow $1 "" "${InstCaption}" "" ""
IsWindow $1 0 CaptionLoop
Abort
FunctionEnd
Section "un.Blank"
SectionEnd
При использовании на Win7 надо позаботиться , чтобы не мешал UAC
Begin2Fly
15-11-2013, 07:15
kotkovets, здравствуйте. Можно что-нибудь придумать с WinVer2.nsh для юникодовой версии NSIS? Желательно для последней альфы.
Используя ${WinVersion} не хочет последнюю цифру рассказывать, получается просто "6."
не хочет последнюю цифру рассказывать, получается просто "6." »
Сколько уже разговоров вокруг определения Win 8.1 ... А надо то всего получить две несчастные циферки 6 и 3
Для 99% практических надобностей, этого достаточно и не надо никаких WinVer.nsh
А получить эти циферки можно или как всегда :
outfile GetOsVersion.exe
Section
ClearErrors
ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion"
MessageBox MB_OK "Номер версии OС : $R0 "
SectionEnd
или
outfile GetOsVersion.exe
Section
System::Call "kernel32.dll::GetVersion() i .r0"
IntOp $4 $0 & 0xFF ;main ver
IntOp $5 $0 & 0xFF00 ;sub ver
IntOp $5 $5 >> 8
Push $5
Push $4
MessageBox MB_OK "Номер версии OС : $4.$5 "
SectionEnd
Begin2Fly
15-11-2013, 13:27
MKN, первый вариант не катит, потому что в реестре кто угодно может поменять эту информацию, а хочется, чтобы всё было как надо.
Второй вариант заинтересовал, благодарю, попробую. И дело вовсе не в 8.1 (чтоб её), на Windows 7 та же беда.
Надеюсь ещё услышать мнение kotkovets.
потому что в реестре кто угодно может поменять эту информацию, »
Интересно, с какой такой целью кому то нужно менять номер версии ОС в реестре ? :) Никогда про такое не слышал... Даже вирусам это не нужно...
В конце концов можно установить сответсвующие права на эту ветку...
Begin2Fly
15-11-2013, 14:14
Интересно, с какой такой целью кому то нужно менять номер версии ОС в реестре ? Никогда про такое не слышал... Даже вирусам это не нужно...
В конце концов можно установить сответсвующие права на эту ветку... »
Да мало ли... Взял кто снёс, или какая недо-чистилка "оптимизировала"... Или какой умный сборщик с ником, заканчивающимся на год рождения. Всё же надёжнее получить информацию от самой ОС, в частности - вызовом функции, как было предложено выше.
kotkovets
15-11-2013, 19:16
kotkovets, здравствуйте. Можно что-нибудь придумать с WinVer2.nsh для юникодовой версии NSIS? »
для какой версии NSIS ?
--
С последней 3 версией NSIS никаких проблем, скрипт сохранял в любом юникоде
http://forum.oszone.net/showpost.php?p=2239933
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC