Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
Смотрите команду SetOutPath. »
Вы меня не совсем поняли или же я не смог донести до вас свою мысль. Я имел ввиду такую ситуацию::
Есть, например, 4 каталога с установленными играми одной серии, на разных дисках в разных каталогах, и вот на них всех должен быть установлен соответствующий софт из одного инсталлера.
Надеюсь так будет понятнее..
Есть, например, 4 каталога с установленными играми одной серии, на разных дисках в разных каталогах, и вот на них всех должно быть установлен соответствующий софт из одного инсталлера. »
Нормальная программа(игра в том числе) как правило, при установке прописывает некоторые данные о себе в реестр (путь установки, версию и т.д.)
Извлекаешь эти данные и делаешь логические выводы, а затем действия...
К примеру :
ReadRegStr $InstPatshGame HKLM "SOFTWARE\GameDeveloper\MyGame\AppsPatch" "GameName"
;MessageBox MB_OK "$InstPatshGame"
${If} ${Errors}
${OrIf} $InstPatshGame == ""
MessageBox MB_OK "Registry Errors. Do not find the Path to the GameName !"IDOK
Quit
${EndIf}
Аналогично смотришь версии, если надо сравниваешь с устанавливаемой...
Если прога дурная и ничего о себе в реестр не пишет, то ищешь соответствующие ей файлы, папки и пр. Если местонахождение известно, то так :
${If} ${FileExists} "$InstPatshGame1\GameName1\GameName1Files.exe"
какое то действие
${Else}
MessageBox MB_OK "GameName1Files.exe file not found !"
${EndIf}
${If} ${FileExists} "$InstPatshGame2, 3, 4 и т.д.
Если местонахождение не известно, то циклом на всех дисках...
(Как это "технически" реализовать в скрипте, значения не имеет...)
Нормальная программа(игра в том числе) как правило, при установке прописывает некоторые данные о себе в реестр (путь установки, версию и т.д.)
Извлекаешь эти данные и делаешь логические выводы, а затем действия... »
Что-то сложна.. Ибо не догоняю пока как можно установить игру одновременно в 4 разных каталога, а потом и удалять корректно из них при деинсталле. Будем разбираться..
как можно установить игру одновременно в 4 разных каталога »
Берем документ "Справочник по NSIS", раздел "Статьи от hb860", глава "Первые шаги" и читаем: "Команда SetOutPath указывает компилятору, куда производить распаковку файлов".
Исходя из постановки задачи, выходит следующая схема:
SetOutPath <каталог 1, версия 1>
File <файл игры 1>
File <файл игры 2>
...
File <файл игры n>
SetOutPath <каталог 2, версия 2>
File <файл игры 1>
File <файл игры 2>
...
File <файл игры n>
SetOutPath <каталог 3, версия 3>
File <файл игры 1>
File <файл игры 2>
...
File <файл игры n>
SetOutPath <каталог 4, версия 4>
File <файл игры 1>
File <файл игры 2>
...
File <файл игры n>
Перед выполнением установки желательно удостовериться, что выбран соответствующей версии каталог игры, что в этом каталоге действительно находятся файлы соответствующей версии игры, и только после этого выполнять установку. Возможные варианты проверок вам указали, также примеры различных проверок вы найдете в "Справочнике по NSIS (http://forum.oszone.net/thread-168287.html)".
удалять корректно из них при деинсталле »
Перед удалением делаете проверку наличия файлов в указанных каталогах, а также их версий (хеш-суммы, размеры и т.п.). Если все проверки удовлетворительные, то выполняете их деинсталляцию.
skinny21
02-07-2018, 13:41
Не получается запустить драйвер SbieDrv.sys через http://nsis.sourceforge.net/NsSCM_plug-in
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SbieDrv]
"Type"=dword:00000001
"Start"=dword:00000003
"ErrorControl"=dword:00000001
"ImagePath"=hex(2):5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,50,00,72,00,6f,00,\
67,00,72,00,61,00,6d,00,20,00,46,00,69,00,6c,00,65,00,73,00,5c,00,53,00,61,\
00,6e,00,64,00,62,00,6f,00,78,00,69,00,65,00,5c,00,53,00,62,00,69,00,65,00,\
44,00,72,00,76,00,2e,00,73,00,79,00,73,00,00,00
"DisplayName"="SbieDrv"
"DependsOnService"=hex(7):46,00,6c,00,74,00,4d,00,67,00,72,00,00,00,00,00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SbieDrv\Instances]
"DefaultInstance"="SbieDrv Instance"
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SbieDrv\Instances\SbieDrv Instance]
"Altitude"="86900"
"Flags"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SbieDrv\Enum]
"0"="Root\\LEGACY_SBIEDRV\\0000"
"Count"=dword:00000001
"NextInstance"=dword:00000001
Не получается запустить драйвер SbieDrv.sys »
Это Sandboxie driver ? Если да, то он устанавливается с помощью собственной утилиты KmdUtil.exe.
Что то вроде : KmdUtil.exe install SbieDrv "Patch\SbieDrv.sys"
Также с помощью этой утилиты можно установить службу-сервис SbieSvc.exe
Утилиту можно "вытащить" из SandboxieInstall (там же кстати будет и NSIS скрипт)...
А NsSCM_plug-in древний и бестолковый... Годится для отдельных частных случаев...
skinny21
03-07-2018, 22:55
MKN
Драйвер установился, но все равно не работает
Exec '"$EXEDIR\App\Sandboxie\KmdUtil.exe" install SbieDrv "$EXEDIR\App\Sandboxie/SbieDrv.sys"'
skinny21, в оригинальном инсталляторе команда установки драйвера выглядит так:
ExecWait "'$PLUGINSDIR\KmdUtil.exe' /lang=$LANGUAGE install SbieDrv '$INSTDIR\SbieDrv.sys' type=kernel start=demand 'msgfile=$INSTDIR\SbieMsg.dll' altitude=86900"
А установка службы вот так:
ExecWait "'$PLUGINSDIR\KmdUtil.exe' /lang=$LANGUAGE install SbieSvc $\"\$\"$INSTDIR\SbieSvc.exe$\"\$\" type=own start=auto 'display=Sandboxie Service' group=UIGroup 'msgfile=$INSTDIR\SbieMsg.dll'"
Допустим, язык можно исключить (параметры /lang и msgfile), но остаются еще другие параметры, которые у вас не указаны. Я не знаю степень их важности, но вы явно что-то упустили из виду.
skinny21,
С слэшем я ошибся - надо Patch\SbieDrv.sys
skinny21
04-07-2018, 13:50
MKN, Исправил, но ошибка та же, драйвер установлен, но не запущен, SbieSvc запустил при помощи SimpleSC
Flix, сделал так как научили, ничего не вышло
Заметил такую странность (точнее, заметили пользователи моей программы) - некоторые функции готового инсталлятора не выполняются, если его заархивировать в WinRar и запустить инсталлятор из архива. В частности через код Function .OnInit может не отработать команда ${If} ${FileExists}. На XP у себя такой проблемы не наблюдаю, а вот на более старших системах баг проявляется, но не всегда. Может кто знает из-за чего такое в принципе может происходить.
Почему спрашиваю: через ${If} ${FileExists} у меня встроена проверка оригинальности файлов при запуске инсталлятора. И эта проверка легко обходится простым архивированием инсталлятора.
Begin2Fly
28-07-2018, 20:39
Serg866, вряд ли она может не отработать, скорее отрабатывает она не так, как вы того ожидаете. Нужно больше информации: часть кода, отвечающая за проверку, может даже установщик чтобы посмотреть на поведение вне архива и в архиве.
Условный код функции
Function .OnInit
MessageBox MB_OK|MB_ICONINFORMATION "Здесь предупреждающий текст" IDOK
Dialer::GetConnectedState
Pop $2
StrCmp $2 "offline" +2
ExecShell "open" "http://forum.oszone.net"
sleep 100
${If} ${FileExists} "$APPDATA\proverka.txt"
${OrIf} ${FileExists} "$EXEDIR\proverka2.txt"
${OrIf} ${FileExists} "$DOCUMENTS\proverka3.txt"
Quit
${EndIf}
FunctionEnd
При запуске инсталлятора из архива, команда ${If} ${FileExists} не выполняет свою задачу, то есть проверка файла не происходит. На XP всё работает нормально.
Замечен баг только на старших системах (Windows 7, 8, 10), но закономерность не обнаружена - на каких-то сборках работает, на каких-то нет.
Использую NSIS 3 (Юникод).
Привет народ.. :)
Заметил очередную странность в работе программы, суть ее вот в чем::
написал инсталлер с установкой проги на 8 языках в зависимости от выбора чекбоксов..
далее, прикрутил автоопределение языка и в зависимости от языка ОС автоматически проставляется галочка на установку аналогичного языка. При инсталляции все работает вроде исправно, но если запускать деинсталл, то чек бокс проставляется на одну строку в низ, а не туда куда нужно..
Пример кода для инсталла и деинсталла для выбора языка установки в чек-боксах::
Function .onInit
Push $R0
SetCurInstType 0
!insertmacro MUI_LANGDLL_DISPLAY
!insertmacro MUI_INSTALLOPTIONS_EXTRACT "setup.ini"
StrCpy $1 ${SecMod}
SetSilent normal
;--------------------------------
# При запуске инсталлятора назначаем секции статус "Отмечена"
${If} $LANGUAGE == ${LANG_ENGLISH}
;IntOp $0 ${SF_SELECTED} // $0
SectionSetFlags ${SecModFiles1} 1
${ElseIf} $LANGUAGE == ${LANG_ROMANIAN}
SectionSetFlags ${SecModFiles2} 1
${ElseIf} $LANGUAGE == ${LANG_GERMAN}
SectionSetFlags ${SecModFiles3} 1
${ElseIf} $LANGUAGE == ${LANG_RUSSIAN}
SectionSetFlags ${SecModFiles4} 1
${ElseIf} $LANGUAGE == ${LANG_ITALIAN}
SectionSetFlags ${SecModFiles5} 1
${ElseIf} $LANGUAGE == ${LANG_CZECH}
SectionSetFlags ${SecModFiles6} 1
${ElseIf} $LANGUAGE == ${LANG_POLISH}
SectionSetFlags ${SecModFiles7} 1
${ElseIf} $LANGUAGE == ${LANG_SPANISH}
SectionSetFlags ${SecModFiles8} 1
${EndIf}
....
Function un.onInit
!insertmacro MUI_UNGETLANGUAGE
Push $R0
StrCpy $1 ${unSecMod}
;--------------------------------
${If} $LANGUAGE == ${LANG_ENGLISH}
;IntOp $0 ${SF_SELECTED} // $0
SectionSetFlags ${SecModFiles1} 1
${ElseIf} $LANGUAGE == ${LANG_ROMANIAN}
SectionSetFlags ${SecModFiles2} 1
${ElseIf} $LANGUAGE == ${LANG_GERMAN}
SectionSetFlags ${SecModFiles3} 1
${ElseIf} $LANGUAGE == ${LANG_RUSSIAN}
SectionSetFlags ${SecModFiles4} 1
${ElseIf} $LANGUAGE == ${LANG_ITALIAN}
SectionSetFlags ${SecModFiles5} 1
${ElseIf} $LANGUAGE == ${LANG_CZECH}
SectionSetFlags ${SecModFiles6} 1
${ElseIf} $LANGUAGE == ${LANG_POLISH}
SectionSetFlags ${SecModFiles7} 1
${ElseIf} $LANGUAGE == ${LANG_SPANISH}
SectionSetFlags ${SecModFiles8} 1
${EndIf}
Как с этим бороться хз, может есть у кого какие мысли ?! :clever-ma
Использую нсис-юникод 2.46.5
Задумал проверять разрешение экрана пользователя.
Пример из справки "Определяем и меняем разрешение экрана" не заработал на NSIS3 (Unicode).
Компилируется без ошибок, но при запуске ничего не происходит.
Используется какой-то древний плагин ChangeRes 2003 года.
Есть ли рабочие примеры проверки разрешения дисплея для NSIS 3 под юникод?
Задумал проверять разрешение экрана пользователя. »
Serg866, очень хорошо подумайте, прежде чем использовать подобный функционал. Ваши пользователи не будут в восторге, когда ваша программа установки сбросит параметры экрана. Функционал в плагине сделан без проверок: количество подключенных устройств, их текущие параметры, сохранение и восстановление этих параметров, поддерживаемые значения режимов, анализ возможных ошибок. По нормальному это нужно все делать, а здесь просто изменяется разрешение экрана и все. И да, сам плагин сделан тогда, когда версии Unicode и в помине не было. Как вариант, используйте сборку ANSI инсталлятора (с директивой Unicode false). Если по каким-то причинам такой вариант неприемлем, то используйте плагин CallAnsiPlugin (http://nsis.sourceforge.net/CallAnsiPlugin_plug-in), который позволяет использовать вызов функций ANSI плагинов в инсталляторах Unicode (с директивой Unicode true).
Есть ли рабочие примеры проверки разрешения дисплея для NSIS 3 под юникод?
Unicode true
Name "Get User Screen Resolution"
Caption "Get User Screen Resolution"
XPStyle "on"
Function .onInit
; Выполняем инициализацию папки для распаковки плагинов
InitPluginsDir
; Устанавливаем каталог распаковки файлов
SetOutPath $PLUGINSDIR
; Записываем файлы плагинов
File "${NSISDIR}\Plugins\x86-unicode\CallAnsiPlugin.dll"
File "${NSISDIR}\Plugins\x86-ansi\ChangeRes.dll"
; Получаем текущие размеры экрана
System::Call 'user32::GetSystemMetrics(i 0) i .r0' ; Ширина в пикселях
System::Call 'user32::GetSystemMetrics(i 1) i .r1' ; Высота в пикселях
; Выводим сообщение с текущим разрешением экрана
MessageBox MB_OK|MB_ICONINFORMATION "Screen Resolution: $\r$\n$0 X $1"
; Изменяем разрешение экрана на 1024х768 пикселей, глубиной цвета 32-бит и частотой обновления 60 Гц
CallAnsiPlugin::Call "$PLUGINSDIR\ChangeRes.dll" ChangeResolution 4 1024 768 32 60
; Получаем новые размеры экрана
System::Call 'user32::GetSystemMetrics(i 0) i .r2' ; Ширина в пикселях
System::Call 'user32::GetSystemMetrics(i 1) i .r3' ; Высота в пикселях
; Выводим сообщение с новым разрешением экрана
MessageBox MB_OK|MB_ICONINFORMATION "New Screen Resolution: $\r$\n$2 X $3"
; Восстанавливаем передыдущее разрешение экрана (условно считаем, что у
; пользователя были установлены глубина цвета 32-бит и частота 60 Гц)
CallAnsiPlugin::Call "$PLUGINSDIR\ChangeRes.dll" ChangeResolution 4 $0 $1 32 60
; Выход
Quit
FunctionEnd
Section "-null"
SectionEnd
Если функционал вашей программы установки активно использует регистры общего назначения, то для хранения исходных значений с размерами экрана лучше задействовать собственные переменные.
Flix, спасибо за подробный разбор!
Я не планировал смену разрешения у пользователей.
Нужно только определять текущее разрешение экрана с целью узнать поддерживает ли монитор Full HD.
Таким образом, если разрешение равно 1920х1080, то один код в инсталляторе. Если нет, то код другой.
Понимаю теперь, что это делается без сторонних плагинов.
Основываясь на Справочнике и Вашем примере, получился такой код функции.
Будет ли сиё работать со всеми Windows от XP до 10? Или что-то нужно добавить?
Function .onInit
; Получаем текущие размеры экрана
System::Call 'user32::GetSystemMetrics(i 0) i .r0' ; Ширина в пикселях
System::Call 'user32::GetSystemMetrics(i 1) i .r1' ; Высота в пикселях
${If} $0 == 1920
${AndIf} $1 == 1080
MessageBox MB_OK "Установлено разрешение 1920x1080"
${Else}
MessageBox MB_OK "Установлено любое другое разрешение"
${EndIf}
FunctionEnd
---------------------------
Если функционал вашей программы установки активно использует регистры общего назначения, то для хранения исходных значений с размерами экрана лучше задействовать собственные переменные. »
Вы о том, чтобы заменить переменные $0 и $1 на созданные? В Справочнике про это написано, но я не разобрался как созданные переменные правильно внедрять в логические конструкции.
Я не планировал смену разрешения у пользователей... Будет ли сиё работать со всеми Windows от XP до 10? Или что-то нужно добавить?»
Serg866, виноват. Понесла меня нелегкая и я развил эту тему в неверном направлении. Да, если просто узнать текущие размеры экрана, то должно работать, криминала в коде никакого нет. Дальше уже сами, по месту смотрите, какие действия предпринимать в зависимости от полученных результатов.
Вы о том, чтобы заменить переменные $0 и $1 на созданные? »
Конечно. Просто объявите собственные переменные и сразу после использования $0 и $1 копируйте их содержимое в ваши переменные. Но если ваш код останется таким же, как показано в вашем примере, то этого делать не обязательно.
agrei678
16-08-2018, 20:16
подскажите , и по возможности кто знает подправьте пожалуйста ,почему скрипт не компилируется? )
Begin2Fly
16-08-2018, 20:28
подскажите , и по возможности кто знает подправьте пожалуйста ,почему скрипт не компилируется? ) »
Потому что это криво распакованная сборка PowerISO (при чём моя), и ничего даже близко похожего к рабочему скрипту здесь нет.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC