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

MaGoth
18-05-2018, 06:19
Смотрите команду SetOutPath. »
Вы меня не совсем поняли или же я не смог донести до вас свою мысль. Я имел ввиду такую ситуацию::
Есть, например, 4 каталога с установленными играми одной серии, на разных дисках в разных каталогах, и вот на них всех должен быть установлен соответствующий софт из одного инсталлера.
Надеюсь так будет понятнее..

MKN
18-05-2018, 10:24
Есть, например, 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 и т.д.


Если местонахождение не известно, то циклом на всех дисках...

(Как это "технически" реализовать в скрипте, значения не имеет...)

MaGoth
20-05-2018, 12:10
Нормальная программа(игра в том числе) как правило, при установке прописывает некоторые данные о себе в реестр (путь установки, версию и т.д.)
Извлекаешь эти данные и делаешь логические выводы, а затем действия... »
Что-то сложна.. Ибо не догоняю пока как можно установить игру одновременно в 4 разных каталога, а потом и удалять корректно из них при деинсталле. Будем разбираться..

Flix
20-05-2018, 18:55
как можно установить игру одновременно в 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

MKN
03-07-2018, 12:48
Не получается запустить драйвер 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"'

Flix
04-07-2018, 00:21
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), но остаются еще другие параметры, которые у вас не указаны. Я не знаю степень их важности, но вы явно что-то упустили из виду.

MKN
04-07-2018, 10:10
skinny21,
С слэшем я ошибся - надо Patch\SbieDrv.sys

skinny21
04-07-2018, 13:50
MKN, Исправил, но ошибка та же, драйвер установлен, но не запущен, SbieSvc запустил при помощи SimpleSC
Flix, сделал так как научили, ничего не вышло

Serg866
28-07-2018, 14:30
Заметил такую странность (точнее, заметили пользователи моей программы) - некоторые функции готового инсталлятора не выполняются, если его заархивировать в WinRar и запустить инсталлятор из архива. В частности через код Function .OnInit может не отработать команда ${If} ${FileExists}. На XP у себя такой проблемы не наблюдаю, а вот на более старших системах баг проявляется, но не всегда. Может кто знает из-за чего такое в принципе может происходить.

Почему спрашиваю: через ${If} ${FileExists} у меня встроена проверка оригинальности файлов при запуске инсталлятора. И эта проверка легко обходится простым архивированием инсталлятора.

Begin2Fly
28-07-2018, 20:39
Serg866, вряд ли она может не отработать, скорее отрабатывает она не так, как вы того ожидаете. Нужно больше информации: часть кода, отвечающая за проверку, может даже установщик чтобы посмотреть на поведение вне архива и в архиве.

Serg866
29-07-2018, 11:38
Условный код функции
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 (Юникод).

MaGoth
29-07-2018, 12:50
Привет народ.. :)

Заметил очередную странность в работе программы, суть ее вот в чем::
написал инсталлер с установкой проги на 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

Serg866
04-08-2018, 17:55
Задумал проверять разрешение экрана пользователя.

Пример из справки "Определяем и меняем разрешение экрана" не заработал на NSIS3 (Unicode).
Компилируется без ошибок, но при запуске ничего не происходит.

Используется какой-то древний плагин ChangeRes 2003 года.

Есть ли рабочие примеры проверки разрешения дисплея для NSIS 3 под юникод?

Flix
05-08-2018, 02:50
Задумал проверять разрешение экрана пользователя. »
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
Если функционал вашей программы установки активно использует регистры общего назначения, то для хранения исходных значений с размерами экрана лучше задействовать собственные переменные.

Serg866
05-08-2018, 15:45
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 на созданные? В Справочнике про это написано, но я не разобрался как созданные переменные правильно внедрять в логические конструкции.

Flix
07-08-2018, 15:26
Я не планировал смену разрешения у пользователей... Будет ли сиё работать со всеми 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