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

» NSIS (Nullsoft Scriptable Install System)

Автор: Victor_VG
Дата сообщения: 23.12.2010 16:17
alroy

Можно. file /ONAME=<имя_устанавливаемого_файла> "имя_файла_источника" . Файлы придётся переименовать с индексами либо распихать по каталогам. Второй приём работает надёжнее чем команда с /oname.
Автор: sawerx
Дата сообщения: 23.12.2010 23:36
может кто подскажет способ или метод, как присвоить ярлыку или файлу совместимость, к примеру с Win98 Me.
строку в реестре вроде бы нашёл, но через Call думаю надёжней будет!
Автор: Victor_VG
Дата сообщения: 24.12.2010 02:54
sawerx

Какой там Call? Просто пишете WriteRegStr/WritRegDWORD что надо и всё. Чего огород-то городить?
Автор: david141
Дата сообщения: 26.12.2010 05:51

Цитата:
Все, проблему решил=) заинклудил ЛогикЛиб и переделал так:
------------------
Function .onInit
CRCCheck::GenCRC "C:\sample.bmp"
Pop $R1
${if} $R1 = "3530642852"
MessageBox MB_OK "Совпадает $R1=3530642852"
${else}
MessageBox MB_OK "Не совпадает $R1<>3530642852"
${endif}
FunctionEnd


Простите за ламерский вопрос.
Как узнать ${if} $R1 = "3530642852"
цифры файла?
Автор: Victor_VG
Дата сообщения: 26.12.2010 08:50
david141

вывести - DetailPrint $R1
Автор: david141
Дата сообщения: 26.12.2010 10:38

Цитата:
вывести - DetailPrint $R1

Пожалуйста можно подробнее.
Автор: Victor_VG
Дата сообщения: 26.12.2010 14:05
david141

в скрипте ставим команду DetailPrint "$$R1=$R1" которая выведет содержимое этого регистра на экран тестового прогона задачи. Это обычный отладочный приём.
Автор: Victor_VG
Дата сообщения: 27.12.2010 06:11
Война с UPX или Микрософт развлекается.

Во многих случаях применение пакеров, даже вроде столь массовых как UPX становится причиной проблем при запуске sприложений под Windows 7. Проблема решается просто - пакеры не применяем, а используем средства сжатия NTFS (на FAT раьботать не будем - она сжатие не поддерживает, вопросы в Редмонд). Можно просто не долго возясь использовать как макрос вот этот кусок кода из установки версии 2.11.1.1.1.1 для моего проекта Far Manager SE2:

Код: IfFileExists $INSTDIR +2
CreateDirectory $INSTDIR
ExecCmd::exec "compact /C /I /A /F /Q /S:$INSTDIR"
Автор: kot280379
Дата сообщения: 27.12.2010 09:32
Victor_VG
Т.е можно упаковать сам инсталлятор после компиляции проекта?
Автор: Victor_VG
Дата сообщения: 27.12.2010 12:00
kot280379

А почему бы и нет? Сжимается каталог вместе с файлами. NTFS это дело умеет делать ещё с 1994-го года, с Windows NT 3.5.0 (Dytona), другое дело, пользуетесь этим лично Вы и как это делаете. Предупрежу сразу - корневой каталог тома (/) сжимать нельзя иначе он чудить станет.
Автор: sawerx
Дата сообщения: 10.01.2011 20:20
kot280379
Посоветуй простой способ вычислить, но только точно, что машина пользователя является именно NT7 (Vista and Win7),
и если да, тогда следует что-то добавить в установку. Желательно по возможности не использовать OS плагин или другие....
Автор: 820815
Дата сообщения: 10.01.2011 21:38
sawerx

Код: !include WinVer.nsh

Function .onInit
${IfNot} ${AtLeastWinVista}
MessageBox MB_OK|MB_ICONSTOP 'Windows Vista or higher required'
Quit
${EndIf}
FunctionEnd
Автор: Victor_VG
Дата сообщения: 11.01.2011 00:08
820815

Не годится. Проще:

Цитата:
Version::GetWindowsVersion
Pop $0 ; $MajorVersion
Pop $1 ; $MinorVersion
StrCpy $0 $0$1
Pop $1
Pop $1
Pop $1
StrCpy $1 0
IntCmpU $0 60 Vista Old +1
IntCmpU $0 61 Win7 Vista WinNew

плагин прочитает версию ОС, а дальше уходим по меткам на нужные ветки алгоритма. Без использования плагина, Вам придётся руками считывать Реестр и писать достаточно громоздкий парсер для его значений. Плагин Version выполнит эту работу за нас, а результат положит на стек. На семёрке он работает, проверялся.
Автор: 820815
Дата сообщения: 11.01.2011 02:59
Да куда уж проще...

Код: ${If} ${IsWinVista}
MessageBox MB_OK 'Running on Vista'
${ElseIf} ${IsWin7}
MessageBox MB_OK 'Running on Seven'
${EndIf}
Автор: Victor_VG
Дата сообщения: 11.01.2011 03:40
820815

Да, до пользовательской ругани, проходили критику за интерактивные диалоги. Нормальный вариант с простейшим парсером вот:

Код: ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion"
StrCpy $1 $0 1 -1
StrCpy $0 $0 1 1
StrCpy $0 $0$1
IntCmpU $0 60 Vista Old +1
IntCmpU $0 61 Win7 Vista WinNew
Автор: kot280379
Дата сообщения: 11.01.2011 11:41
Victor_VG

Цитата:
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion"

Согласен, проще не бывает, но проще и бывает изменить значение CurrentVersion
Итог будет ясен.
Я лично использую winver.nsh. Эта библиотека использует system.dll. - наиболее часто используемый
плагин в скриптах, а при использовании еще MUI2 - грех не воспользоваться.
Дык и надежней.

Код:
!include "WinVer.nsh"
OutFile "setup.exe"

Function .onInit
${WinVerGetMajor} $1
IntCmp $1 6 +3
MessageBox MB_OK|MB_ICONSTOP "Запуск возможен только в Windows Vista/7"
Quit
FunctionEnd

Section "Main"
SectionEnd
Автор: Victor_VG
Дата сообщения: 11.01.2011 12:40
kot280379

Да, этот фокус возможен, но нам поставлено конкретное условие, и приведённое решение написано точно под него. Собственно для того и писалось. Я могу себе позволить любую чертовщину где угодно, но в рамках ТЗ, а здесь оно меня чётко ограничивает в выборе средств - только коды NSIS, никаких плагинов. Согласен? Я вот сейчас вожусь со сборкой TDM-GCC 4.5.1 R1 - переделываю в очередной раз. Там я ограничен только одним - размером скрипта. Сейчас это почти 1,7 Мб, в итоге HM NIS ругается что ОЗУ не хватает. Ну, с этим справляется лобовой вызов makensis из под Far Manager благо NSIS специально в пути прописан. Посему достаточно по Ctrl+G его вызывать универсальной командой makensis !.! и сам far перебрасывает скрипт на компилятор. И всей возни сейчас - подобрать имя пакета так, чтобы оно влезло в окно инсталлятора. Всё остальное в порядке. Скромное количество - 1027 каталогов, 13672 файла - либы, хидеры, бинарники. А куда я денусь? Там в одном пакете C/C++/C#/Ada/Fortran95 компиляторы с обвеской, рунтаймом и кучей UNIX утиля. Вышло в сумме 29227 строк. На чём с учётом объёма возни HM NIS падает. Ну, сиё его проблемы.
Автор: kot280379
Дата сообщения: 11.01.2011 13:48

Цитата:
меня чётко ограничивает в выборе средств - только коды NSIS, никаких плагинов. Согласен?

Согласен, но часто бывает задача стоит, что только кодами NSIS - скрипты получаются весьма громоздкими, трудно читаемы и со временем, если нужно что-то подправить, начинаешь чесать затылок - а че такое я натворил а? ау? но тут можно долго спорить, да и не нужно...

Цитата:
подобрать имя пакета так, чтобы оно влезло в окно инсталлятора

Ну если вы используете MUI, то решение есть в справочнике по NSIS, который я выкладывал.
Victor_VG
Вы не знаете способ, как внести запись в ветку HKLM, под ограниченной учеткой пользователя?
Есть плагин http://nsis.sourceforge.net/AccessControl_plug-in - как я понял, дает права админа пользователю. Но с кучей бесполезных попыток на WinXP - не удалось внести запись в ветку HKLM



Автор: sawerx
Дата сообщения: 16.01.2011 18:22
Спасибо, что откликнулись!
Смысл предложных решений, вроде простой и понятный, но в этом случае как мне передать какой нибудь секции, которая находится в конце (в пост инстале) что ей можно выполнить при условии, что в начале скрипта найдено, что это Win7-Vista, и без всяких лишних окон.
Автор: Victor_VG
Дата сообщения: 16.01.2011 18:44
kot280379

Под XP только одним способом, но гарантированным - вызвать установку с правами админа. Или писать что-то по смыслу похожее на утилиты типа "Run as...." запускающими специально напасанный модуль с админскими правами и запросом пары логин - пароль. Но могу точно сказать - я такое писал года два назад для одной работы, и у меня тогда вышел монстр от которого я мигом отказался и код его потёр - громоздкий код, очень неудобный в применении и вдобавок слишком не предсказуемым вышло его поведение. Потому я думаю, что проще использовать системную команду "Run As..."

sawerx

А зачем Вам окна выводить? Ставите в заголовке программы блок переменных-семафоров (var ...), в .onInit присваиваете этим переменным значение 0, и если условие их срабатывания соблюдено, то ставим им 1, а потом переход с проверкой их как условия. Сам так делаю. У меня в Far Manager SE целая куча подобных проверок имеется, и без семафоров реализовать тот ИИ, что заложен в программу я бы не сумел.

Только учтите, что если Вы сами не инициализируете переменную, её начальное значение буден непредсказуемо. Инициализация любых переменных до их первого применения - это надёжный метод предотвращения связанных с их начальным состоянием ошибок, и делать это надо всегда
Автор: kot280379
Дата сообщения: 16.01.2011 21:48
Victor_VG
Понял, запустил от админа - пошло дело. Спасибо за подсказку!

Цитата:
sawerx

В последнем примере, если это Vista/7, в переменную $1 cваливается значение 6. По этой переменной можно определять какие фунции выполнять:

Код:
Section "Vista_7"
StrCmp $1 6 0 notVista_7
;здесь будут команды выполняться только в Vista/7
notVista_7:
SectionEnd
Автор: dimbat
Дата сообщения: 16.01.2011 22:41
К слову о встроенной возможности - WinVer.nsh всё таки дает сбой.
Пользую в одном скрипте ${If} ${AtMostWin2000} (т.е. версии ХР и выше) - два раза давала сбой на ХР (сервис-паки 1 и 2) и почему-то только на Home Edition. И это были не левые самосборы, а оригинальные винды.
Хз почему не проходит проверку, но как факт.
---
"SOFTWARE\Microsoft\Windows NT\CurrentVersion" тоже не идеален - ведь достаточно случаев изменения этого параметра с целью там например приручить какую-нить игру к не поддерживаемой операционке, ну или около того...
Автор: Victor_VG
Дата сообщения: 16.01.2011 23:03
kot280379

Обязательно используйте свою группу переменных-семафоров с понятными Вам именами! Переменные с именами $0 - $19 это регистры с именами $r0 - $r9 ($0 - $9) и $R0 - $9 ($10 - $19) соответственно. Их начальное значение так же не предсказуемо.

Пример как это обычно реализую я:

Цитата:
....
/* $s0 - $s17 - это глобальные переменные-семафоры для отслеживания состояния событий. благодаря их глобальному объявлению. они доступны во всей нашей программе.

Пр необходимости мы можем в нужных секциях или функциях определить локальные семафоры, но лучше тогда использовать регистры предварительно сохранив их в стеке и сразу после завершения участка кода где мы это делаем восстановив их оттуда. */
var s0
var s1
.....
var s17
.....
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
/* инициализируем объявленные семафоры */
StrCpy $s0 0
StrCpy $s1 0
....
SytCpy $s17 0
/* Инициализируем остальные переменные и регистры $0 - $19, последние можно конечно не сбрасывать, но сразу после старта программы в них мусор, потому лучше их тут вычистим */
....
FunctionEnd
.....
/* здесь в отдельных функциях сидят разные проверки и вывод диагностических сообщений. В .onInit этому коду делать нечего! Он там только вызовет сбои!*/
....
Section
/* первая неименованная секция играет роль основного модуля управления программы, весь код управления или код который не должен быть пропущен кидаем в нё */
SectionEnt
Section "Main"
.....
SectionEnd

С такими приёмами работает в основном без ошибок, но и то они иной раз вылезают, и порой трудно уловимые.


Добавлено:
dimbat

Да, я согласен. Остаётся только один вариант с вызовом плагина GetVersion и с его помощью читать версию ядра и сервис пака. Эти метки обычно надёжнее. Я так всегда и поступаю. Те вызовы API что применяет WinVer это примерно то же что я выше писал - чтение из HKLM, только разница в том, кто именно данный алгоритм отработал WinAPI или мы сами.
Автор: dimbat
Дата сообщения: 16.01.2011 23:14
Victor_VG

Цитата:
один вариант с вызовом плагина GetVersion

Ну я как бы в пользу этого плага и писал пост выше
Главное, не забывать его обновлять периодически. А то тоже были прецеденты...
Автор: Victor_VG
Дата сообщения: 16.01.2011 23:30
dimbat

Да согласен, ошибки в нём автор правит исправно. Вот ещё бы Registry автор поправил, но там я ещё сам не точено понял отчего не понятную кодировку вместо кириллицы словил. При случае проверю.
Автор: sawerx
Дата сообщения: 17.01.2011 21:26
Всем спасибо кто откликнулся, за семафоры отдельное мерси, оно стоит того, и ещё спасибо за то, что ваше обсуждение выявили то, в чем я подспудно сомневался.

И ешё мне интересно, кто, как проверяет свои творения на предмет ошибок.
Автор: Victor_VG
Дата сообщения: 17.01.2011 21:52
sawerx

Я поступаю просто - сомнительные куски кода проверяю на тестовых сборках, типа такого варианта:

Код: OutFile test.exe
ShowInstDetails show
Var s17
Section
GetVersion::WindowsVersion
Pop $s17
StrCpy $1 $s17
Push $0
StrCpy $0 $s17 1
StrCpy $s17 $s17 1 -1
StrCpy $s17 $0$s17
Pop $0
DetailPrint "$$1 == $1"
DetailPrint "$$s17 == $s17"
SectionEnd
Автор: Victor_VG
Дата сообщения: 19.01.2011 04:26
Ну, кому свежих багов отсыпать? К автору сего "творения" обращаться бесполезно - парень на баг-репорты отвечает просто "Не вижу необходимости исправлять!". Пары месяцев бодания с ним и в итоге не исправленного бага ( не просто так он там до сих пор висит!) хватило.

На сей раз баг снова в старом месте, Reg2Nsis. Только поковарнее будет. Проявляется он просто - при конвертации автомат убирает ведущие нули сдвигая строку вывода в NSH-файле влево. Итог - например сбитые параметры запуска программы, на что я в Far Manager SE2 нарвался. Причём доказать себе, что это именно баг конвертера, а не моя собственная ошибка стоило времени и сил. Вот какие параметры имеет конвертер:

Цитата:
Reg2Nsis version 0.14 (C) Artem Zankovich <aarrtteemm@nm.ru>
Converts registry informarion into NSIS-script commands

Usage:
    Reg2Nsis (reg-file | reg-key) [-r] [(-o nsis-file | -O)]

Parameters:
    reg-file -- take values from the specified REG-file
    reg-key -- take values from the specified registry key
    -r -- iterate through registry subkeys recurrently (if
     source is registry key)
    -o nsis-file -- send output to the specified file
    -O -- send output to the file with the same name as
     inputed REG-file but with the .nsh file extention
    -s -- disable special folder substitution

параметра управления удалением/усечением символов в них нет, следовательно мы вправе ожидать получения не искажённой информации, но....

Вот вам пример:

test1.reg:

Цитата:
REGEDIT4

[HKEY_CURRENT_USER\Software\Far2\System]
"ElevationMode"=dword:ffffffff

test2.reg:

Цитата:
REGEDIT4

[HKEY_CURRENT_USER\Software\Far2\System]
"ElevationMode"=dword:0fffffff

Обратите внимание на значение и размер строки:
размер строки 4 байта, 8 hex-цифр, и значения:

в первом случае "ElevationMode"=dword:ffffffff , а во втором "ElevationMode"=dword:0fffffff

И вот результат конверсии:

первый случай:

WriteRegDWORD HKEY_CURRENT_USER "Software\Far2\System" "ElevationMode" 0xffffffff

значение содержит 8 цифр

И второй случай:

WriteRegDWORD HKEY_CURRENT_USER "Software\Far2\System" "ElevationMode" 0xfffffff


значение содержит 7 цифр - это что за фортеля

внешне, на первый взгляд всё выглядит правильно, но! посчитайте во первых число цифр, и во во вторых сравните значения на входе конвертера и его выходе. На лицо потеря данных и их искажение.
В итоге параметры запуска программы сбиваются, и как проявление этого видим такой диалог на ровном месте:



получается, что мне по милости этого халтурщика придётся в том же Far Manager SE2 перелопачивать вручную почти 170 Кб реестровый скрипт, не говоря уже о других проектах - видимо не менее 1/3 баг-репортов по ним были заложены этим его решением "убирать ведущие нули". Да, это допустимо в некоторых случаях, но если это цифровые значения такой фортель не допустим абсолютно. А если по его милости будет изменён код запуска ядерной ракеты? И что потом говорить что из-за его художеств мы получили вторую Хиросиму? Да за такие вещи надо башку отрывать вместе со всем что выступает за пределы корпуса ещё в роддоме.
Автор: kot280379
Дата сообщения: 19.01.2011 10:27
Никогда не доверял таким рода утилиткам - лишний раз убедился!
Делаю код записей реестра по старинке - вручную, геморно...но надежней и значения двордов в коде пишу в десятичном ввиде - ни разу не подводило
Автор: Victor_VG
Дата сообщения: 19.01.2011 18:39
kot280379

Так вот, в чём и причина - спасибо, что по мей просьбе уважаемый ADMIN_CRACK посмотрел что там творится:

Цитата:
Дело в том что значения заносятся в цикле по байтам и первый байт выглядит 0f и он естественно записывается как f , вот если бы в исходниках он сразу поместил 0fffffff как переменную а потом её внес в строку было бы другое дело.
Тем более что это помещается в регистры но потом с какого то перепуга начинает заносится по байтам.

Это называется "святых выноси". Когда скрипт не велик руками бить его быстро, а когда как у Far за 170 Кб? Тут руками быстро не напишешь, ноа что видать и расчёт автора - в массе строк его халтура проскочит. В данном случае имеет место грубейшая ошибка в алгоритме разбора двоичной строки - с какого перепугу он её начинает побайтно анализировать, и вдобавок заведомо не корректно?

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364

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


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