Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Написание скрипта для инсталлятора
Форум программистов > Системное программирование > Delphi и Pascal > Delphi - FAQ
Страницы: 1, 2, 3, 4, 5, 6
Kindly
(Вопрос по Inno Setup 5) Я извиняюсь за вопрос немножко не в тему. Меня интереcует написание скрипта на Pascal следующего характера: Перед запуском инсталлятора нужна проверка реестра на определённый ключ, и если он существует - должен запускаться мастер инсталляции, а если ключ не существует, то должна вылетать мессага, что прога не найдена - жмите OK чтобы покинуть мастер (ну или другой текст). Вобщем вы программеры - для вас скриптик или только секцию кода написать не составит труда. Поможете такому как мне?
mailto:gubei_vadim@list.ru
zubr
Пример проверки инсталлятором установлена ли в системе Delphi, если нет, то инсталляция завершается:
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;
Kindly
zubr, спасибо огромноеtongue.gif. Классно у Вас, программеров, всё получается! Может покажусь слишком наглым, но позвольте спросить ещё про одну фичу...
Например, я создал русификатор, который поместил в инсталлятор (Inno Setup 5). Проверка на ключ прошла успешно, путь установки также взят из реестра - жмём "Установить"///
Вопрос следующий: имеется ли возможность у самого инсталлятора проверять наличие определённого файла в папке назначения после нажатия кнопки "Установить". Например, если файл отсутствует (который должен проверяться) - должно появиться сообшение "Выбрана неверная папка!" (или т.п.). Если не трудно, опишите это, пожалуйста, на примере - этим Вы поможете многим локализаторам софта.
Ну, и чтобы лишний раз не постить, спрошу; если вышеописанная функция возможна, то возможна ли проверка требуемого файла (в папке назначения) на такие атрибуты как размер и CRC сумма?
zubr
Цитата
Вопрос следующий: имеется ли возможность у самого инсталлятора проверять наличие определённого файла в папке назначения после нажатия кнопки "Установить". Например, если файл отсутствует (который должен проверяться) - должно появиться сообшение "Выбрана неверная папка!" (или т.п.).

Такая возможность есть. Вот пример кода, где имя файла www.sss:
[Code]

function NextButtonClick(CurPage: Integer): Boolean;
var
 s:string;
begin
Result:=True;
If CurPage=5 then
begin
 If FileSearch('www.sss', ExpandConstant('{app}'))='' then
 begin
  s:='В каталоге '+ExpandConstant('{app}')+' файл www.sss отсутствует!';
  MsgBox(s, mbError, mb_Ok);
  Result:=False;
 end;
end;
end;

Здесь CurPage=5. Определить CurPage можно в отладке. Запускаешь процесс инсталляции в InnoSetup клавишей F7, когда шаг доходит до строки CurPage, наводишь на нее курсор, всплывающая подсказка покажет значение CurPage.
Цитата
если вышеописанная функция возможна, то возможна ли проверка требуемого файла (в папке назначения) на такие атрибуты как размер и CRC сумма?

В самом InnoSetup это невозможно, но можно сделать программку, которая будет находиться в дистрибутиве и при установке запускаться программой установки, выполнив соответствующие проверки, удаляться.
Kindly
Цитата
В самом InnoSetup это невозможно, но можно сделать программку, которая будет находиться в дистрибутиве и при установке запускаться программой установки, выполнив соответствующие проверки, удаляться.

В смысле, внешняя программка сначала будет загружаться и, обнаружив файл, проверит, например, CRC сумму и выдаст сообщение, например "У вас программа соответствующей версии. Запустить мастер установки?"
Или эта программка будет вызываться инсталлятором для проверки непосредственно перед самим процессом инстялляции, и после проверки будет ли программка посылать ответ инталлятору, который будет принимать соответствующие дейтвия?
zubr Вы из Беларуси? Я - да. Вы уже в курсе дела, может договоримся о написании Вами этой программки?
zubr
Цитата
В смысле, внешняя программка сначала будет загружаться и, обнаружив файл, проверит, например, CRC сумму и выдаст сообщение, например "У вас программа соответствующей версии. Запустить мастер установки?"

Эта программка будет запакована в инсталляционный файл вместе с другими файлами инсталляционного пакета.
Цитата
Или эта программка будет вызываться инсталлятором для проверки непосредственно перед самим процессом инстялляции, и после проверки будет ли программка посылать ответ инталлятору, который будет принимать соответствующие дейтвия?

Лучше всего сделать, чтобы мастер установки запускал эту программку проверки, когда юзер выбрал каталог, куда будет устанавливаться ваша программа. Программка выполнит проверки, и в зависимости от результатов выполнит соответствующие действия (даст возможность продолжить процесс установки; выдаст сообщение о невозможности дальнейшей установки и остановит процесс установки и т. п.)
Я тоже из Беларуси. Напишите мне rozin@tut.by
Kindly
Пока я думаю, как правильно сформулировать свою просьбу, позвольте задать ещё один вопрос:
Как сделать чтобы при перезаписи оригинальных файлов создавались их резервные копии (у меня получались резервные копии тех файлов, которые были в инсталляторе). Причём резервные файлы чтобы сохранялись в папку, например: "backup", без переименования расширений. И возможно ли сделать так, чтобы пользователю предоставлялась возможность в самом инсталляторе предварительно отметить/поставить галочку на это действие (на подобии как в патчере-инсталляторе PatchWise Free)?
zubr
Цитата
Как сделать чтобы при перезаписи оригинальных файлов создавались их резервные копии (у меня получались резервные копии тех файлов, которые были в инсталляторе).

Опять таки искать файл и если он есть, создать папку "backup", к примеру, в том же каталоге куда устанавливается программа, и скопировать файл в "backup". Все это можно сделать средствами InnoSetup.
Цитата
И возможно ли сделать так, чтобы пользователю предоставлялась возможность в самом инсталляторе предварительно отметить/поставить галочку на это действие (на подобии как в патчере-инсталляторе PatchWise Free)?

Можно через компоненты.
У меня на работе под рукой Inno Setup нет, подробнее смогу, если время будет вечером.
zubr
[Components]
Name: "Backup"; Description: "Backup"; Types: full

[Files]
Components: Backup; Source: "MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion; Check: MyProgCheck

[Code]

function MyProgCheck():boolean;
var
   s1, s2:string;
begin
Result:=True;
s1:=ExpandConstant('{app}')+'\MyProg.exe';
s2:=ExpandConstant('{app}')+'\Backup';
If FileExists(s1) then
begin
 CreateDir(s2);
 FileCopy(s1, s2+'\MyProg.exe', False);
end;
end;

Здесь файл MyProg.exe и есть с которого делается копия.
Kindly
Долго не имел возможности ответить, поэтому сейчас выражаю безразмерную благодарность за оказанную Вами, zubr, помощь. Что касается "окончательного" вопроса, так он состоит в следующем:
Можно ли в Inno Setup произвести деинсталляцию так, чтобы при удалении установленных файлов, при предварительном создании резервных копий перезаписываемых файлов, резервные файлы восстанавливались на свои прежние места, а сама папка (резервных файлов) удалялась?
zubr
Чисто средствами Inno Setup такое не получится. Это надо будет делать свой UnInstall.exe, а в проекте Inno Setup сделать следующее:
[Files]
Source: "MyProg.exe"; Flags: onlyifdoesntexist uninsneveruninstall
Source: "UnInstall.exe"

[UninstallRun]
Filename: "{app}\UnInstall.exe"
Kindly
Спасибо большое! Благодаря Вам я узнал всё то, что меня интересовало по данной теме. Хорошо хоть "земляки" откликнулись, а то на российских форумах молчат =).
zubr
Рад был помочь rolleyes.gif
Kindly
У меня всё ещё появилось два вопроса следующего содержания.
1. Всё-таки сохранение резервных файлов через Компоненты влечёт добавление в инсталлятор дополнительных файлов, из-за чего размер инсталлятора может оказаться довольно большим. Вопрос состоит в том, как изменить расширения перезаписываемых оригинальных файлов, например, на *.bak или *.exe.bak при перезаписи обновлёнными (чтобы без добавлеине резервируемых файлов)?
2. В Inno Setup 5 всё-таки имеется функция подсчёта размера файла. Только я не въезжаю как секцию правильно написать. В хелпе написано следующее:

Образец:
function FileSize(const Name: String; var Size: Integer): Boolean;
Описание:
Задаёт Size - размер указанного файла в байтах. Возвращает True, если размер файла задан успешно, иначе возвращает False.

Помогите, пожалуйста, вписать вышеупомянутую функцию так, чтобы она выполняла проверку уже после нажатия кнопки "Установить", т.е. перед самим процессом инсталляции и так, чтобы при несоответствии размера вылетало собщение, после которого мастер установки прекращал дальнейшие действия, или чтобы данная проверка запускалась сразу после проверки на наличие определённого файла в папке с программой.
zubr
Цитата
Всё-таки сохранение резервных файлов через Компоненты влечёт добавление в инсталлятор дополнительных файлов, из-за чего размер инсталлятора может оказаться довольно большим. Вопрос состоит в том, как изменить расширения перезаписываемых оригинальных файлов, например, на *.bak или *.exe.bak при перезаписи обновлёнными (чтобы без добавлеине резервируемых файлов)?

Непонятно какие файлы на какие вы будете перезаписывать, если в инсталляторе ничего не будет.
Цитата
В Inno Setup 5 всё-таки имеется функция подсчёта размера файла. Только я не въезжаю как секцию правильно написать. В хелпе написано следующее:

Образец:
function FileSize(const Name: String; var Size: Integer): Boolean;
Описание:
Задаёт Size - размер указанного файла в байтах. Возвращает True, если размер файла задан успешно, иначе возвращает False.

Да функция FileSize, но вам же надо было еще CRC.
Функция FileSize работает следующим образом: в переменной Name имя и путь к проверяемому файлу, в переменной Size, после выполнения функции будет размер проверяемого файла. Если функция сработала успешно, то она возвращает True, в противном случае False.
function NextButtonClick(CurPage: Integer): Boolean;
var
s:string;
sz:Integer;
begin
Result:=True;
If CurPage=5 then
begin
If FileSearch('www.sss', ExpandConstant('{app}'))='' then
begin
   s:='В каталоге '+ExpandConstant('{app}')+' файл www.sss отсутствует!';
 MsgBox(s, mbError, mb_Ok);
 Result:=False;
end
else
begin
 If FileSize(ExpandConstant('{app}')+'\www.sss',  sz) then
 begin
  If sz<>2840 then//2840 - проверяемый размер
  begin
   s:='Файл www.sss несоответствует!';
   MsgBox(s, mbError, mb_Ok);
   Result:=False;
  end;
 end;
end;
end;
end;
Kindly
Хоть я и не соображаю в программировании, но здесь более удачное решение сохранения резервных копий файлов без изменения расширения, и без всяких компонентов.

Цитата
procedure CurStepChanged(CurStep: TSetupStep);
var
s1, s2:string;
begin
s1:=ExpandConstant('{app}')+'\My.exe';
s2:=ExpandConstant('{app}')+'\Backup';
If FileExists(s1) then
begin
CreateDir(s2);
FileCopy(s1, s2+'\My.exe', True);
end;
end;


Здесь резервное копирование оригинального файла происходит после нажатия кнопки "Установить", а если файл не существует, то будет создан BACKUP того файла, что установился из инсталлятора, если отключены проверки на его присутствие.
Kindly
Вопрос следующий:
Здесь идёт проверка на присутствие двух определённых файлов: 'my.dll' и 'my.exe'.
При отсутствии 'my.exe' - вылетает мессага, а при отсутствии 'my.dll'- ничего не вылетает, но установка не продолжается. А если вписать мессагу после проверки 'my.dll', то проверка 'my.exe' при присутствии в порверяемой папке 'my.dll' будет игнорироваться. Как правильно вклеить мессагу так, чтобы все проверки совершались правильно и чтобы после удачных проверок не вылетало "лишнего" сообщения? В чём недочёт или ошибка?

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


ОГРОМНОЕ СПАСИБО.
zubr
Цитата
Хоть я и не соображаю в программировании, но здесь более удачное решение сохранения резервных копий файлов без изменения расширения, и без всяких компонентов.

Ну вы сами спрашивали:
Цитата
Как сделать чтобы при перезаписи оригинальных файлов создавались их резервные копии (у меня получались резервные копии тех файлов, которые были в инсталляторе). Причём резервные файлы чтобы сохранялись в папку, например: "backup", без переименования расширений. И возможно ли сделать так, чтобы пользователю предоставлялась возможность в самом инсталляторе предварительно отметить/поставить галочку на это действие (на подобии как в патчере-инсталляторе PatchWise Free)?

Компоненты позволяют, чтобы пользователь мог сделать выбор. Не понимаю почему вы считаете, что компоненты добавляют файлы в инсталлятор. От того что у вас 2 компонента с одинаковым файлом, это не значит, что инсталлятор скомпонуется с 2-мя одинаковыми файлами.
Цитата
Здесь идёт проверка на присутствие двух определённых файлов: 'my.dll' и 'my.exe'.
При отсутствии 'my.exe' - вылетает мессага, а при отсутствии 'my.dll'- ничего не вылетает, но установка не продолжается. А если вписать мессагу после проверки 'my.dll', то проверка 'my.exe' при присутствии в порверяемой папке 'my.dll' будет игнорироваться. Как правильно вклеить мессагу так, чтобы все проверки совершались правильно и чтобы после удачных проверок не вылетало "лишнего" сообщения? В чём недочёт или ошибка?

Здесь можно сделать так:
function NextButtonClick(CurPage: Integer): Boolean;
var
 s:string;
begin
Result:=True;
If CurPage=6 then
begin
If (FileSearch('my.dll', ExpandConstant('{app}')='') or (FileSearch('my.exe', ExpandConstant('{app}')='') then
begin
 s:='Выбрана неверная папка!';
 MsgBox(s, mbCriticalError, mb_Ok);
 Result:=False;
end;
end;
end;
Kindly
Цитата
Здесь можно сделать так:


А ещё так:

Цитата
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;

Это ж можно проверить абсолютно все файлы!
Kindly
Помогите, пожалуйста, логически завершить данную секцию кода. Здесь происходит проверка размера файла после нажатия кнопки "Установить", а также резервное копирование оригинального файла:
Цитата
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;

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

[Types]
Name: "Backup"; Description: "Выборочная установка"; Flags: iscustom

так красивее. Спасибо за "ошибку":)!
zubr
Цитата
Всё таки с резервным копированием я окончательно разобрался. Оказывается, когда Вы предложили решение с копированием через компоненты - всё было правильно, но в функции MyProgCheck нужно было задать True вместо False в FileCopy. Задание False всё-таки подразумевает копирование дополнительно включаемых файлов в инсталлятор.

В функции FileCopy, если 3-й параметр в False, то функция копирует файл в указанный каталог не проверяя существует там уже такой файл или нет, а при параметре True, такая проверка осуществляется. На размер вашего инсталлятора значение данного параметра повлиять никак не должно, а будут устанавливаться дополнительные файлы или нет, зависит от выбора пользователя, не в зависимости от данного параметра.
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" выводимого сообщения о несоответствии размера? Сделать "аборт", короче говоряsmile.gif. Вычитал в хелпе, что это можно сделать через коды выхода инсталлятора, но как?
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;
Kindly
Спасибо. Но у меня пятая версия. Как тогда расписать функцию Terminated, чтобы она возможно заработала в этой версии?
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;
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 не там где надоsad.gif. Но на самом деле - я на данный момент узнал всё, что меня интересовало по данному поводу. Поэтому Вам, zubr, я выражаю огромную благодарность за оказаннуя помощь. Используя Ваши примеры я даже самостоятельно уже начал что-то составлять, а это уже о чём-то для меня говорит.
zubr
Цитата
Вопрос: ничего страшного, когда компилятор выдаёт ошибку, а готовый инсталлятор нет?

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

Ну паскаль вы уже почти освоили, так что дерзайте rolleyes.gif
Kindly
У меня к Вам созрело несколько вопросов: первый - инсталлятор ведь может проигрывать музыку, какую и как правильно функцию расписать? Второй, т.е. уже третий и четвёртый - возможно ли проигрывание трекерной музыки в формате *.xm, если только через *.dll, то можно ли использовать для этого плагин от Winamp-а?
Kindly
Извиняюсь за офтопик, но не знаю куда и кому написать следующий вопрос:
Многие инсталляторы создают логи, в которых можно засечь инсталляцию всех файлов и значений реестра. Но возникает проблема, когда надо перепаковать программу, в которой не было этого лога, например, его использование было отключено. С помощью какой программы-шпиона можно вычислить все происходящие события в Windows, т.е. например: какие файлы и когда были переименованы, установленны, перемещены; какие значения в реестр добавляются и т.п.? Чтобы правильно собрать инсталлятор.
zubr
FileMon, RegMon, а также различные отладчики типа W32dsm
Kindly
С отладчиками чет не очень, но File Mon рулит, сенкс.
Вопрос следующий: Написал я скрипт, в котором при инициализации проверяется присутствие определенного ключа, и, если он существует, то выводится сообщение о том, не желает ли пользователь удалить уже установленное приложение "Yes/No" (это если инсталлятор запускается второй раз). При этом напрямую прописывается путь к деинсталлятору, например:
{win}\proga\unins00.exe
И через функцию Exec выполняется деинсталлятор, если пользователь выберет "Yes".
Вопрос в том, имеет ли Inno Setup возможность запускать приложения или выполнять другие файлы исходя из значений реестра? Например, если путь деинсталлятора прописан в папку с программой; ведь при инициализации это (если возможно) уже нужно делать через реестр же?
Kindly
Может начинаю надоедать - вопрос другой, т.е. повторюсь.
Возможно ли проигрывание музыки XM или MOD в инсталляторе через соответствующую .dll-ку XM_Music.dll ? Вот она:
]]>http://make3d.narod.ru/xm_music/index.htm]]>
Если ссылка не рабочая, то попробуйте скачать XM_Music.dll отсюда:
]]>http://user.kem.ru/pro/delphi_utl.php]]>
Если будет время и настроение, то посмотрите, пожалуйста, можно ли с этим что либо сделать?
zubr
Будет время, гляну ваши вопросы.
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;
_dimka_
вообще не по теме вопрос
zubr
_dimka_
Вообще то тема называется Delphi и Pascal. В инсталляторе InnoSetup используются скрипты на языке Pascal, так что вполне в тему.
Kindly
Zubr, спасибо большое. Вы как всегда на высотеsmile.gif!
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).
А дальше не врубаюсь, помогите, пожалуйста...
zubr
Вот код решающий оба ваших вопроса:
function InitializeSetup(): Boolean;
var
 res:Integer;
 s, ResultStr:string;
begin
ExtractTemporaryFile(music.mp3');
s:=ExpandConstant('{tmp}')+'\music.mp3';
ShellExec('play',  s,  '',  '',  SW_HIDE,  ewNoWait,  res);
If RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\My Program_is1', 'UninstallString', ResultStr) then
begin
 If ResultStr<>'' then
 begin
  ResultStr:=RemoveQuotes(ResultStr);
  If MsgBox('Программа My Program уже установлена, удалить ее?', mbInformation, MB_OKCANCEL)=IDOK then
  InstExec(ResultStr, '', '', True, False, SW_SHOW, res)
  else
  begin
   Result:=False;
   exit;
  end;
 end;
end;
Result:=True;
end;
Kindly
Спасибо Вам, будем пробоватьsmile.gif.
Kindly
Получилось, но всё равно немного переделал под пятую версию:

Цитата
function InitializeSetup(): Boolean;
var
res:Integer;
ResultCode: Integer;
s, ResultStr:string;
begin
ExtractTemporaryFile('Temp_Program.exe');
s:=ExpandConstant('{tmp}')+'\Temp_Program.exe';
Exec(s, '', '', SW_SHOWMINIMIZED, ewNOWait, res);
Result:=True;
begin
If RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Restorator 2005_is1', 'UninstallString', ResultStr)
then
begin
If ResultStr<>''
then
begin
ResultStr:=RemoveQuotes(ResultStr);
If MsgBox('Программа My Program уже установлена, удалить ее?', mbInformation, MB_OKCANCEL)=IDOK
then
  if not Exec(ResultStr, '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode)
then
  MsgBox('Ошибка удаления. ' #13#13 '' + SysErrorMessage(ResultCode) + '.' #13#13 'Вероятно, деинсталлятор был перемещен, удален или переименован.', mbError, MB_OK);
end;
end;
end;
end;


Вопрос следующий: как закрыть (или завершить процесс) программу, запущенную из временной папки перед завершением установки, используя средства Inno Setup? Это ведь лучше через процедуру DeInitializeSetup делать?
У меня после успешного решения данного вопроса сразу отпадает потребность воспроизведения *.xm и *.mod, т.к. уже найден конвертер этих файлов в EXE. На данный момент это последнее, что меня интересует. Поможете?
zubr
Цитата
Вопрос следующий: как закрыть (или завершить процесс) программу, запущенную из временной папки перед завершением установки, используя средства Inno Setup?

Если программка Temp_Program.exe не консольная, то можно передать ей сообщение WM_CLOSE, иначе проблема сложнее, средствами InnoSetup не получится.
procedure DeInitializeSetup();
var
 h:Longint;
begin
h:=FindWindowByClassName('WMPlayerApp');
If h<>0 then
SendMessage(h, 16, 0, 0);
end;

Здесь 'WMPlayerApp' класс окна закрываемого приложения, чтобы его определить можно воспользоваться программой VIEWWIND.
Kindly
Спасибо, очень интересно. Я вот не знаю даже: сама программка Temp_Program.exe не консольная, т.е. обычное Win32 приложение, которое напоминает классический интерфейс Winamp-а, но она создана консольным "Досовским" приложением, поэтому я теряюсь в точном ответе, т.к. не знаю, может ли считаться программа Win32, если она была создана Досовским/консольным приложением. Но судя по всем признакам (проверка PE анализаторами) - программка не консольная.
Получается, что дело остаётся "за малым". Какую-то программу VIEWWIND я нашёл через поисковик, но что-то сомневаюсь, что она может определить класс окна приложения. Сама по себе она консольная и даже не имеет описания, как ей пользоваться, даже не запускается через командную строку (возможно, это исходникиsad.gif. Поэтому я прошу Вас очень, - укажите, пожалуйста, ссылку, по которой можно скачать данную программу.
zubr
В вашем случае, если при проигрывании звукового файла, вы закрываете программку Temp_Program.exe и проигрывание прекращается, то все должно получиться.
Программу ViewWindow отправил вам на Email.
Kindly
Спасибо большое. Очень хорошая программка.
Kindly
Всё получилось, только есть один момент:

Код

Цитата
procedure DeInitializeSetup();
var
h:Longint;
begin
h:=FindWindowByClassName('XM-EXE-WINDOW');
If h<>0 then
SendMessage(h, 16, 0, 0);
begin
MsgBox('Работа мастера завершена.', mbInformation, MB_OK);
end;
end;


Когда инсталлятор закрывается, программа Temp_Program.exe закрывается, но не удаляется, т.к. видимо не хватает времени для выгрузки из временной директории. Поэтому мне пришлось "схитрить", вставив соответствующее сообщение. Вопрос: можно ли заставить выгружаться временные файлы (в данном случае) при выходе инсталлятора без соответствующего сообщения, например, сделать задержку?

И ещё один, думаю, понравитсяsmile.gif.
Есть такая директива AppMutex. Эта директива используется для предотвращения установки новой версии программы, если программа выполняется в данный момент, и удаления запущенного в данный момент приложения. В ней нужно указать ограничители. Если ограничители присутствуют, инсталятор/деинсталятор выдаст сообщение: "[Setup или Uninstall] обнаружил, что [AppName] выполняется. Пожалуйста, завершите работу приложения, а потом нажмите ОК для продолжения или Cancel для отмены". Но для этого нужно добавление в программу/инсталлятор соответствующего кода. Например, вот код на Delphi:

Цитата
CreateMutex(nil, False, 'MyProgramsMutexName');


А в секции Setup после этого прописать следующее:

Цитата
AppMutex=MyProgramsMutexName


Вот только не знаю как расписать код для создания Mutex.
Если Вам не сложно, напишите, пожалуйста, примерчик.
zubr
Цитата
Вопрос: можно ли заставить выгружаться временные файлы (в данном случае) при выходе инсталлятора без соответствующего сообщения, например, сделать задержку?

Попробуйте вместо функции MsgBox поставить функцию Sleep(500) - здесь аргумент 500 количество милисекунд задержки.
Цитата
Есть такая директива AppMutex. Эта директива используется для предотвращения установки новой версии программы, если программа выполняется в данный момент, и удаления запущенного в данный момент приложения.

Есть смысл использовать данную директиву, если вы делаете инсталлятор для своей программы, в которой вы можете установить мутекс, как в Help написано CreateMutex(nil, False, 'MyProgramsMutexName'). В вашем случае так не получится, но можно исхитриться по другому, все через тот же класс окна:
function InitializeSetup(): Boolean;
var
 h:Longint;
begin
Result:=True;
h:=FindWindowByClassName('ClassWindowInstallProg');//ClassWindowInstallProg - класс окна программы, которую вы устанавливаете
If h<>0 then
begin
//здесь вы можете выдать сообщение, что открыта программа
SendMessage(h, 16, 0, 0);//закрытие программы
//можно не закрывать программу, а выдать сообщение и закрыть инсталлятор
Result:=False;//закрытие инсталлятора
end;

end;
Kindly
Спасибо большое. Думаю, разберусь с этим и всё будет правильно работать.
Zubr, а Вы настоящий Гуру в написании скрипта для инсталлятора (да и не только, наверноеsmile.gif.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2009 IPS, Inc.