Написание скрипта для инсталлятора

  • Автор темы Kindly
  • Дата начала
Статус
Закрыто для дальнейших ответов.
Z

zubr

А ещё так:


Цитата

function NextButtonClick(CurPage: Integer): Boolean;
var
s:string;
begin
Result:=True;
If CurPage=6 then
begin
If FileSearch('my.dll', ExpandConstant('{app}'='' then
begin
s:='Выбрана неверная папка!';
MsgBox(s, mbCriticalError, mb_Ok);
Result := False
end
else
begin
If FileSearch('my.exe', ExpandConstant('{app}'=''
then
begin
s:='Выбрана неверная папка!';
MsgBox(s, mbCriticalError, mb_Ok);
Result:=False;
end;
end;
end;
end;



Это ж можно проверить абсолютно все файлы!
Все таки красивее будет мой вариант:
Код:
If (FileSearch('my.dll', ExpandConstant('{app}')='') or (FileSearch('my.exe', ExpandConstant('{app}')='') then
Для следующего файла добавляете or (FileSearch('next.exe', ExpandConstant('{app}')='')
Помогите, пожалуйста, логически завершить данную секцию кода. Здесь происходит проверка размера файла после нажатия кнопки "Установить", а также резервное копирование оригинального файла:

Цитата

procedure CurStepChanged(CurStep: TSetupStep);
var
s, s1, s2:string;
sz:Integer;
begin
If FileSize(ExpandConstant('{app}'+'\#1 DVD Ripper.exe', sz) then
begin
If sz<>921600 then
begin
s:='Несоответствие размера файла! Обновляемый файл изменён или имеет другую версию. Операция отменена!';
MsgBox(s, mbCriticalError, mb_Ok);
end
else
begin
s1:=ExpandConstant('{app}'+'\#1 DVD Ripper.exe';
s2:=ExpandConstant('{app}'+'\Backup';
If FileExists(s1) then
begin
CreateDir(s2);
FileCopy(s1, s2+'\#1 DVD Ripper.exe', True);
end;
end;
end;
end;
Ну здесь, во первых, надо добавить
Код:
If CurPage=6 then
иначе проверка на размер файла будет проводиться на всех шагах установки, что может вызвать исключительную ситуацию.
Чтобы дальше установка не продолжалась, если проверка не прошла делаете так:
Код:
If sz<>921600 then
begin
s:='Несоответствие размера файла! Обновляемый файл изменён или имеет другую версию. Операция отменена!';
MsgBox(s, mbCriticalError, mb_Ok);
Result:=False;
end
 
K

Kindly

CПАСИБО!
Всё таки с резервным копированием я окончательно разобрался. Оказывается, когда Вы предложили решение с копированием через компоненты - всё было правильно, но в функции MyProgCheck нужно было задать True вместо False в FileCopy. Задание False всё-таки подразумевает копирование дополнительно включаемых файлов в инсталлятор. (Например, очень даже полезно при инсталляции перепакованной игры при отметке юзером "Русская версия" - происходит установка русификатора (дополнительно включаемых файлов), а при неотмеченном компоненте - русификатор устанавливаться не будет. Может есть и проще решение для этого, но вполне для этого годится и такой вариант.) А что б не было назойливого выбора типов установки следует написать:
[Components]
Name: "Backup"; Description: "Сохранить резервные копии файлов"

[Types]
Name: "Backup"; Description: "Выборочная установка"; Flags: iscustom
так красивее. Спасибо за "ошибку":ph34r:!
 
Z

zubr

Всё таки с резервным копированием я окончательно разобрался. Оказывается, когда Вы предложили решение с копированием через компоненты - всё было правильно, но в функции MyProgCheck нужно было задать True вместо False в FileCopy. Задание False всё-таки подразумевает копирование дополнительно включаемых файлов в инсталлятор.
В функции FileCopy, если 3-й параметр в False, то функция копирует файл в указанный каталог не проверяя существует там уже такой файл или нет, а при параметре True, такая проверка осуществляется. На размер вашего инсталлятора значение данного параметра повлиять никак не должно, а будут устанавливаться дополнительные файлы или нет, зависит от выбора пользователя, не в зависимости от данного параметра.
 
K

Kindly

Что-то не действует Ваш "красивый" совет по поводу:
If (FileSearch('my.dll', ExpandConstant('{app}')='') or (FileSearch('my.exe', ExpandConstant('{app}')='') then
компилятор выдаёт: "Close round expected."

Помогите решить следующую задачу
У меня получилось:
procedure CurPageChanged(CurPage: Integer);
var
s:string;
sz:Integer;
begin
If CurPage=12 then //где CurPage=12 страница с индикатором установки
begin
If FileSize(ExpandConstant('{app}')+'\#1 DVD Ripper.exe', sz) then
begin
If sz<>921600 then
begin
s:='Несоответствие размера файла! Операция отменена!';
MsgBox(s, mbCriticalError, mb_Ok);
end;
end;
end;
end;
Тут проверка на размер, но после нажатия кнопки "Установить", т.е. перед самим инсталляционным процессом. Показывается окно с индикатором инсталляции и выводится при несоответствии размера сообщение. Кстати в этой процедуре не работает значение Result, оно подбирается автоматически, но установка после нажатия кнопки "OK" всплывающего сообщения на данном примере продолжается. Как сделать так, чтобы при несоответствии размера файла перед появлением соответствующего сообщения инсталлятор вообще досрочно закрывался, т.е. полностью прекращал свою работу, а после полного закрытия выводилось вышеупомянутое сообщение. Если так невозможно, то как сделать так, чтобы инсталлятор полностью закрывался после нажатия кнопки "OK" выводимого сообщения о несоответствии размера? Сделать "аборт", короче говоря:eek:. Вычитал в хелпе, что это можно сделать через коды выхода инсталлятора, но как?
 
Z

zubr

Что-то не действует Ваш "красивый" совет по поводу:

Цитата

If (FileSearch('my.dll', ExpandConstant('{app}'='' or (FileSearch('my.exe', ExpandConstant('{app}'='' then



компилятор выдаёт: "Close round expected."
Важно правильно расставлять символы, в данном случае скобки. Еще раз повторяю код:
Код:
If (FileSearch('my.dll', ExpandConstant('{app}'))='') or (FileSearch('my.exe', ExpandConstant('{app}'))='') then
Тут проверка на размер, но после нажатия кнопки "Установить", т.е. перед самим инсталляционным процессом. Показывается окно с индикатором инсталляции и выводится при несоответствии размера сообщение. Кстати в этой процедуре не работает значение Result, оно подбирается автоматически, но установка после нажатия кнопки "OK" всплывающего сообщения на данном примере продолжается. Как сделать так, чтобы при несоответствии размера файла перед появлением соответствующего сообщения инсталлятор вообще досрочно закрывался, т.е. полностью прекращал свою работу, а после полного закрытия выводилось вышеупомянутое сообщение. Если так невозможно, то как сделать так, чтобы инсталлятор полностью закрывался после нажатия кнопки "OK" выводимого сообщения о несоответствии размера? Сделать "аборт", короче говоря. Вычитал в хелпе, что это можно сделать через коды выхода инсталлятора, но как?
Есть в InnoSetup функция Terminated, но она почему то не работает (у меня 4-ая версия). Насчет кода выхода, они только для того, чтобы знать по какой причине был закрыт инсталлятор, сами коды инсталлятор не закрывают. Вот еще вариант:
Код:
If FileSize(ExpandConstant('{app}')+'\#1 DVD Ripper.exe', sz) then
begin
If sz<>921600 then
begin
 s:='Несоответствие размера файла!';
 MsgBox(s, mbError, mb_Ok);
 WizardForm.Close;
 Result:=False;
end;
end;
 
K

Kindly

Спасибо. Но у меня пятая версия. Как тогда расписать функцию Terminated, чтобы она возможно заработала в этой версии?
 
Z

zubr

Код:
If FileSize(ExpandConstant('{app}')+'\#1 DVD Ripper.exe', sz) then
begin
If sz<>921600 then
begin
s:='Несоответствие размера файла!';
MsgBox(s, mbError, mb_Ok);
Terminated;
end;
end;
 
K

Kindly

Всё таки я переделал это так:

procedure CurStepChanged(CurStep: TSetupStep);
var
s:string;
sz:Integer;
begin
If CurStep=ssInstall
then
begin
If FileSize(ExpandConstant('{app}')+'\#1 DVD Ripper.exe', sz)
then
begin
If sz<>921600
then
begin
s:='Несоответствие размера главного файла #1 DVD Ripper.exe! Операция отменена.';
MsgBox(s, mbCriticalError, mb_Ok);
WizardForm.Close;
Abort;
end;
end;
end;
end;
Дописал Abort;, потому что как бы всё правильно, но при откате изменений сохраняются резервные копии файлов, если предварительно отметить эту опцию. Но есть один недостаток. При тестировании компилятор выдаёт как бы ошибку, если дело доходит до операции Abort, но как ни странно, сам инсталлятор ошибки не выдаёт. Но после Abort откат идёт по полной, т.е. уже файлы не резервируются. Вопрос: ничего страшного, когда компилятор выдаёт ошибку, а готовый инсталлятор нет?
Но когда форма закрывается ещё нужно написать:

procedure CancelButtonClick(CurPage: Integer; var Cancel, Confirm: Boolean);
begin
Cancel:=True;
If CurPage=12
then
begin
Confirm:=False;
end;
end;
Это чтобы не вызывалось на той странице сообщения с вопросом "Прекратить установку?"
Только оно как-то расписано некрасиво. В смысле var не там где надо:). Но на самом деле - я на данный момент узнал всё, что меня интересовало по данному поводу. Поэтому Вам, zubr, я выражаю огромную благодарность за оказаннуя помощь. Используя Ваши примеры я даже самостоятельно уже начал что-то составлять, а это уже о чём-то для меня говорит.
 
Z

zubr

Вопрос: ничего страшного, когда компилятор выдаёт ошибку, а готовый инсталлятор нет?
Протестируйте инсталлятор в разных системах, на разных компьютерах, если работать будет корректно, то и хрен с ошибкой компилятора.
Используя Ваши примеры я даже самостоятельно уже начал что-то составлять, а это уже о чём-то для меня говорит.
Ну паскаль вы уже почти освоили, так что дерзайте :)
 
K

Kindly

У меня к Вам созрело несколько вопросов: первый - инсталлятор ведь может проигрывать музыку, какую и как правильно функцию расписать? Второй, т.е. уже третий и четвёртый - возможно ли проигрывание трекерной музыки в формате *.xm, если только через *.dll, то можно ли использовать для этого плагин от Winamp-а?
 
K

Kindly

Извиняюсь за офтопик, но не знаю куда и кому написать следующий вопрос:
Многие инсталляторы создают логи, в которых можно засечь инсталляцию всех файлов и значений реестра. Но возникает проблема, когда надо перепаковать программу, в которой не было этого лога, например, его использование было отключено. С помощью какой программы-шпиона можно вычислить все происходящие события в Windows, т.е. например: какие файлы и когда были переименованы, установленны, перемещены; какие значения в реестр добавляются и т.п.? Чтобы правильно собрать инсталлятор.
 
Z

zubr

FileMon, RegMon, а также различные отладчики типа W32dsm
 
K

Kindly

С отладчиками чет не очень, но File Mon рулит, сенкс.
Вопрос следующий: Написал я скрипт, в котором при инициализации проверяется присутствие определенного ключа, и, если он существует, то выводится сообщение о том, не желает ли пользователь удалить уже установленное приложение "Yes/No" (это если инсталлятор запускается второй раз). При этом напрямую прописывается путь к деинсталлятору, например:
{win}\proga\unins00.exe
И через функцию Exec выполняется деинсталлятор, если пользователь выберет "Yes".
Вопрос в том, имеет ли Inno Setup возможность запускать приложения или выполнять другие файлы исходя из значений реестра? Например, если путь деинсталлятора прописан в папку с программой; ведь при инициализации это (если возможно) уже нужно делать через реестр же?
 
K

Kindly

Может начинаю надоедать - вопрос другой, т.е. повторюсь.
Возможно ли проигрывание музыки XM или MOD в инсталляторе через соответствующую .dll-ку XM_Music.dll ? Вот она:

Если ссылка не рабочая, то попробуйте скачать XM_Music.dll отсюда:

Если будет время и настроение, то посмотрите, пожалуйста, можно ли с этим что либо сделать?
 
Z

zubr

Вопрос в том, имеет ли Inno Setup возможность запускать приложения или выполнять другие файлы исходя из значений реестра? Например, если путь деинсталлятора прописан в папку с программой; ведь при инициализации это (если возможно) уже нужно делать через реестр же?
Код:
function InitializeSetup(): Boolean;
begin
Result:=True;
If (not RegKeyExists(HKLM, 'SOFTWARE\Borland\Delphi\5.0')) and
(not RegKeyExists(HKLM, 'SOFTWARE\Borland\Delphi\6.0')) and
(not RegKeyExists(HKLM, 'SOFTWARE\Borland\Delphi\7.0')) then
begin
MsgBox('Not found Delphi on our computer', mbError, mb_Ok);
Result:=False;
end;
end;
Это пример, как проверить установлена ли в системе Delphi. В вашем случае, аналогично, надо проверить присуствие определенного ключа в реестре и если он есть, прочитать значение ключа, где указан путь к unins00.exe, затем получив путь к данному файлу, запустить его функцией InstShellExec, см. пример ниже.
Возможно ли проигрывание музыки XM или MOD в инсталляторе через соответствующую .dll-ку XM_Music.dll ?
Средствами InnoSetup проигрывание музыки в формате XM или MOD сделать большой гимор, если вообще возможно, практически не пробовал. Можно сделать для этого программку, которую запускать в InnoSetup, а еще проще вот вариант, с помощью которого можно запустить звуковой файл менее экзотического формата (*.wav, mp3 и т. п.):
Код:
function InitializeSetup(): Boolean;
var
res:Integer;
begin
Result:=True;
InstShellExec('D:\mus.mp3', '', '', SW_HIDE, res);
end;
 
Z

zubr

_dimka_
Вообще то тема называется Delphi и Pascal. В инсталляторе InnoSetup используются скрипты на языке Pascal, так что вполне в тему.
 
K

Kindly

Zubr, спасибо большое. Вы как всегда на высоте:)!
 
K

Kindly

Такой функции (InstShellExec) в пятой версии вроде как нет, но можно и так:

function InitializeSetup(): Boolean;
var
res: Integer;
begin
Result:=True;
ShellExec('play', ExpandConstant('{sd}\music.mp3'), '', '', SW_HIDE, ewNoWait, res)
end;

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

Вот это мне действительно нужно: я так и не разобрался:

function InitializeSetup(): Boolean;
var
ResultStr: String;
ResultCode: Integer;
begin
Result:=True;
RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Program_is1', 'UninstallString', ResultStr);
if ResultStr='???' \\ведь константа какая-то нужна? Или это лишнее?
then
begin
if not ShellExec(???), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode)
then
MsgBox('Ошибка удаления.' #13#13 '' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
end;
end;

Ну, вроде как функцию RegQueryStringValue надо использовать, так?
Ну, вроде считываем параметр деинсталлятора - 'UninstallString'.
Ну, вроде ResultStr - это и есть (значение) прямой путь к деинсталлятору (включая сам деинсталлятор *.exe).
А дальше не врубаюсь, помогите, пожалуйста...
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!