PDA

Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 [38] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

kotkovets
09-11-2013, 19:53
Моя интуиция подсказывает, что эти две, правильно ? »
альтернативы не существует :biggrin:

MKN
10-11-2013, 10:44
как-то можно сгенерировать случайное число ? »
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

MKN
11-11-2013, 12:44
Возможно ли в NSIS реализовать мониторинг создания ключей реестра, какой либо программой ?
Т.е. перехват обращений к реестру. Вроде как для этого есть функция CmRegisterCallback...
Вскользь про это было здесь : http://www.xakep.ru/magazine/xa/102/114/1.asp

kotkovets
11-11-2013, 14:24
Возможно ли в NSIS реализовать мониторинг создания ключей реестра, какой либо программой ? »
если кто-то напишет драйвер для NSIS..
А нужно ли это установщику?

MKN
11-11-2013, 14:40
А нужно ли это установщику? »
Появляется всё больше программ, "генерирующих" различные уникальные и не очень, ключи и данные в реестр (часто только при первом запуске ! ), которые после деинсталляции, как штатной, (так и организованной разработчиком NSIS дистрибутива) - не удаляются из реестра.
То что эти ключи и данные остаются в реестре - полбеды. В ряде случаев именно из-за их наличия, не возможно повторно установить программу, либо программа просто не станет работать...
Поэтому полная зачистка реестра от этой заразы, как перед установкой, так и при деинсталляции ПО, была бы очень полезна. Поэтому есть смысл мониторить образование таких ключей
если кто-то напишет драйвер для NSIS.»
Понятно, т.е. - этого не будет никогда...

MKN
12-11-2013, 13:37
Когда то рассматривался вопрос об использовании в качестве картинок - файлов формата 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

MKN
13-11-2013, 11:38
При создании на стандартной финишной странице отмеченного чекбокса ( 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

vahe-91
13-11-2013, 12:17
Не помню спрашивал или нет :unsure: Можно как-то упростить создание деинсталера, чтобы вручную не указать что, где нужно удалять ?

MKN
13-11-2013, 12:39
Можно как-то упростить создание деинсталера, чтобы вручную не указать что, где нужно удалять ? »
Есть uninstlog.nsh
http://nsis.sourceforge.net/Talk:Uninstall_only_installed_files
и
http://nsis.sourceforge.net/Advanced_Uninstall_Log_NSIS_Header
Но по моему, это не серьёзно... Годится только для частных случаев... Кто лучше самого создателя инсталлятора, может лучше знать что, как и когда удалять, условия и нюансы удаления ?

vahe-91
13-11-2013, 13:03
Но по моему, это не серьёзно... Годится только для частных случаев... Кто лучше самого создателя инсталлятора, может лучше знать что, как и когда удалять, условия и нюансы удаления ? »
Иногда нужно удалить файлы из папки, где до установки уже были файлы и после деинсталяции они не должны удаляться...в таких случаях очень неудобно вместо RMDIR /r целой папки, вручную писать команду удаления для каждого файла.

MKN
14-11-2013, 12:06
Автоматическая смена заголовка окна сообщений

Занятное решение...

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."

MKN
15-11-2013, 11:52
не хочет последнюю цифру рассказывать, получается просто "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.

MKN
15-11-2013, 13:45
потому что в реестре кто угодно может поменять эту информацию, »
Интересно, с какой такой целью кому то нужно менять номер версии ОС в реестре ? :) Никогда про такое не слышал... Даже вирусам это не нужно...
В конце концов можно установить сответсвующие права на эту ветку...

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