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

» Inno Setup (создание инсталяционных пакетов)

Автор: maxdddca123
Дата сообщения: 28.12.2006 16:33
Genri
Уже лучше, правда неособо, сначала несколько раз пишет невозможно найти файл (я снял флаг)
(когда code:CurrentDir|{#i}} равно ''), затем распаковывает всё таки нужный файл, и после мноооооооооооого раз пишет опять ошибку list of index out of bouunds. Осталось немножко додумать....
Автор: Genri
Дата сообщения: 28.12.2006 16:56
Попробуй следующее:
[Run]
#sub RunFile
Filename: "{code:RunDir|{#i}}\ExtForms\Rp06q3.grp\akciz5.exe"; StatusMsg: Распаковка форм...; Flags: skipifdoesntexist
#endsub

#for {i = 0; i < MaxTarget; i++} RunFile

а в секцию Code добавь функцию:

function RunDir(Param: string): string;
begin
if (StrToInt(Param) < Page.CheckListBox.Items.Count) and
Page.CheckListBox.Checked[StrToInt(Param)] then
Result:= Page.CheckListBox.ItemCaption[StrToInt(Param)]
else Result:= '';
end;

... и постарайся найти время, чтобы разобраться в том, что все это значит. Потом легче будет.


Добавлено:

Цитата:
(я снял флаг) (когда code:CurrentDir|{#i}} равно '')
-- это не понял. Функцию CurrentDir менять не надо. А то ты так наменяешь, что перестанет работать даже то, что сейчас работает.


Добавлено:
Ну а для окончательной красоты, добавь следующее:
1. В начале секции Code, пропиши еще одну переменную:
ProgressBar: TNewProgressBar;

2. Секцию Run измени на следующее:
[Run]
#sub RunFile
Filename: "{code:RunDir|{#i}}\ExtForms\Rp06q3.grp\akciz5.exe"; StatusMsg: Распаковка форм {code:RunDir|{#i}}; BeforeInstall: ChangeProgress ; Flags: skipifdoesntexist
#endsub

#for {i = 0; i < MaxTarget; i++} RunFile

3. И в секцию Code добавь две процедуры:
Код:
procedure ChangeProgress();
begin
ProgressBar.Position:= ProgressBar.Position + 1;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
CheckedCount, i: integer;
begin
if CurStep = ssInstall then
begin
CheckedCount:= 0;
for i:= 0 to Page.CheckListBox.Items.Count - 1 do
begin
if Page.CheckListBox.Checked[i] then
CheckedCount:= CheckedCount + 1;
end;
with WizardForm.ProgressGauge do
begin
ProgressBar := TNewProgressBar.Create(WizardForm);
ProgressBar.Left := Left;
ProgressBar.Top := Top + Height + ScaleY(8);
ProgressBar.Width := Width;
ProgressBar.Height := Height;
ProgressBar.Parent := WizardForm.InstallingPage;
ProgressBar.Max := CheckedCount;
ProgressBar.Position := 0;
end;
end;
end;
Автор: maxdddca123
Дата сообщения: 28.12.2006 20:22
Спасибо, но с Filename: "{code:RunDir|{#i}} файл опять не запускается (всегда берёт Result:= ''), а с CurrentDir|{#i}} запускается с ошибками как я выше описывал.... Я расстроился, думал уж получится
Автор: Genri
Дата сообщения: 28.12.2006 20:29
maxdddca123 -- давай опять весь код в ПМ
Автор: maxdddca123
Дата сообщения: 28.12.2006 20:36
Послал. Жду вашей реакции магистр
Автор: Genri
Дата сообщения: 28.12.2006 23:57
maxdddca123 -- Проблема в том, что я все примеры давал из расчета, что в CheckListBox пути к базам сохраняются в Caption, а у тебя они сохраняются в SubItem. Вобщем-то можно и так и так (влияет только на отображение в списке). Но тогда соответствующим образом надо поменять и код. Подробнее в ПМ.
Автор: GRom V
Дата сообщения: 29.12.2006 02:01
/feandy/
/так сделай проверку

if FileExists('backup.reg') then
regedit /s backup.reg/

У меня в конце инсталляции запускается прога, после ее закрытия запускается ват-ник,в котором такие строчки:
regedit /s UninstallRegInfo.reg
regedit /s backup.reg
Erase backup.reg

Какой указать параметр чтобы вслучае отсуствия backup.reg ошибка не выскакивала???

Добавлено:
if FileExists('backup.reg') then
regedit /s backup.reg/

не работает эта тема

Добавлено:
Все!!! надо было так:
if Exist backup.reg regedit /s backup.reg
Автор: maxdddca123
Дата сообщения: 29.12.2006 06:05
Genri
Да, виновать Эт всё предновогодние отмечания
Спасибо, а ещё подскажи такой ньюансик:
у меня распаковываются много ехе файлов, и после распаковки надо поочерёдно, что бы запустились все. Можно конечно каждый файл поотдельности прописать, но это неудобно. Можно ли сделать так, что бы это одной строкой было прописано.
Вот так не работает если в [Run] прописать:

Filename: {code:RunDir|{#i}}\ExtForms\Rp06q3.grp\*.exe;

Добавлено:
Даже есть ещё очень красивый вариан: есть текстовый файл с названиями всех екзешников:
// Отчетность за 4 квартал 2006 года;
AKCIZ.EXE;Акцизы
AKCIZN3.EXE;Акцизы на алкогольную продукцию, реализуемую оптом
AKCIZ5.EXE;Акцизы на нефтепродукты
AKCIZ9.EXE;Акцизы на подакцизное минеральное сырье
AKCIZN7.EXE;Акцизы на табачные изделия
BUH.EXE;Бухгалтерская отчетность
вот если бы отсюда брать их имена и подставлять в RUN былл бы просто мегаааа красиво. Можно так сделать?

Добавлено:
Думаю тут пригодится ф-ция LoadStringsFromFile, но вот как отделить название файла от остальной строки ума не приложу ? (понятно что надо брать все символы до ; )
Автор: omals
Дата сообщения: 29.12.2006 09:48
2 maxdddca123

Цитата:
Думаю тут пригодится ф-ция LoadStringsFromFile, но вот как отделить название файла от остальной строки ума не приложу ? (понятно что надо брать все символы до ; )

а може проще просто текстовый файл подредактировать?

ну если не хочеться то мона так:

var
ArrOfFiles:TArrayOfString
I, J: integer;
tmpStr:STRING;
begin

if LoadStringsFromFile('путь с именем к вашему текстовому файлу, например: {app}\exelist.txt', ArrOfFiles) then
begin
for I:=0 to GetArrayLength(ArrOfFiles)-1 do
begin
J:=Pos(';', ArrOfFiles[I]);
tmpStr:=Copy(ArrOfFiles[I], 0, J-1);
MsgBox(tmpStr, mbError, MB_OK);
//а можноArrOfFiles[I]:= tmpStr -- в результате будет масив со всеми .exe файлами
end;
end
else MsgBox(невозможно открыть файл', mbError, MB_OK);

вроде так (ну суть точно такая
Автор: maxdddca123
Дата сообщения: 29.12.2006 10:39
omals
Thx, попробую.

Как правильно использовать function FileCopy, если мне нужно все файлы из одной дирректории скопировать в другую... ?

Ох уж эти скрипты ((((
Автор: feandy
Дата сообщения: 29.12.2006 11:30
maxdddca123
Например так

var
FindRec: TFindRec;


if FindFirst('SourceDir\*', FindRec) then begin
try
repeat
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
FileCopy('SourceDir\'+FindRec.Name, 'DestDir\'+FindRec.Name, False);
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
Автор: Genri
Дата сообщения: 29.12.2006 11:46
Итак, попробуем резюмировать все, что мы тут совместными усилиями построили.

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

Вариант решения можно посмотреть [more=здесь]
Код:
[Setup]
AppName=My Program
AppVerName=My Program version 1.5
Uninstallable=No
DisableProgramGroupPage=Yes
CreateAppDir=No
AlwaysShowDirOnReadyPage=Yes

[Files]
#define MaxTarget 200
#define i

#sub AddFile
Source: Files\*; DestDir: {code:CurrentDir|{#i}}; Check: NeedCopy(ExpandConstant('{#i}'))
#endsub

#for {i = 0; i < MaxTarget; i++} AddFile

[Run]
#sub RunFile
Filename: "{code:RunDir|{#i}}\Archive.exe"; StatusMsg: Распаковка форм {code:RunDir|{#i}}; BeforeInstall: ChangeProgress(ExpandConstant('{#i}')) ; Flags: skipifdoesntexist
#endsub

#for {i = 0; i < MaxTarget; i++} RunFile

[Code]
var
Names: TArrayOfString;
Value: TArrayOfString;
Page: TInputOptionWizardPage;
ProgressBar: TNewProgressBar;
SelectAll: TButton;

function NeedCopy(Param: string): Boolean;
begin
if (StrToInt(Param) < Page.CheckListBox.Items.Count) and
Page.CheckListBox.Checked[StrToInt(Param)] then
begin
Result:= True;
end;
end;

function CurrentDir(Param: string): string;
begin
if Page.CheckListBox.Checked[StrToInt(Param)] then
Result:= Page.CheckListBox.ItemSubItem[StrToInt(Param)]
else Result:= '';
end;

function RunDir(Param: string): string;
begin
if (StrToInt(Param) < Page.CheckListBox.Items.Count) and
Page.CheckListBox.Checked[StrToInt(Param)] then
Result:= Page.CheckListBox.ItemSubItem[StrToInt(Param)]
else Result:= '';
end;

procedure ChangeProgress(Param: string);
begin
if (StrToInt(Param) < Page.CheckListBox.Items.Count) and
Page.CheckListBox.Checked[StrToInt(Param)] then
ProgressBar.Position:= ProgressBar.Position + 1;
end;

procedure CurPageChanged(CurPageID: Integer);
var
i: integer;
begin
if CurPageID = wpReady then
begin
with WizardForm.ReadyMemo.Lines do
begin
Clear;
Add('Destination location:');
for i:= 0 to Page.CheckListBox.Items.Count - 1 do
begin
if Page.CheckListBox.Checked[i] then
Add(#9 + Page.CheckListBox.ItemSubItem[i] +
' - ' + Page.CheckListBox.ItemCaption[i]);
end;
end;
end;

if CurPageID = Page.ID then
begin
SelectAll.Visible:= True;
end else
SelectAll.Visible:= False;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
CheckedCount, i: integer;
begin
if CurStep = ssInstall then
begin
CheckedCount:= 0;
for i:= 0 to Page.CheckListBox.Items.Count - 1 do
begin
if Page.CheckListBox.Checked[i] then
CheckedCount:= CheckedCount + 1;
end;
with WizardForm.ProgressGauge do
begin
ProgressBar := TNewProgressBar.Create(WizardForm);
ProgressBar.Left := Left;
ProgressBar.Top := Top + Height + ScaleY(8);
ProgressBar.Width := Width;
ProgressBar.Height := Height;
ProgressBar.Parent := WizardForm.InstallingPage;
ProgressBar.Max := CheckedCount;
ProgressBar.Position := 0;
end;
end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var
i: integer;
begin
if CurPageID = Page.ID then
begin
Result := False;
for i:= 0 to Page.CheckListBox.Items.Count - 1 do
begin
if (Page.CheckListBox.Checked[i]) then
begin
Result := True;
Break;
end;
end;
if Not Result then MsgBox('Выберите хотя бы один путь установки !', mbInformation, MB_OK);
end else
begin
Result := True;
end;
end;

procedure ButtonOnClick(Sender: TObject);
var
i: integer;
begin
if (SelectAll.Tag = 0) then
begin
for i:= 0 to Page.CheckListBox.Items.Count - 1 do
begin
Page.CheckListBox.Checked[i]:= True;
end;
SelectAll.Caption := 'Очистить все';
SelectAll.Tag:= 1;
end else
if (SelectAll.Tag = 1) then
begin
for i:= 0 to Page.CheckListBox.Items.Count - 1 do
begin
Page.CheckListBox.Checked[i]:= False;
end;
SelectAll.Caption := 'Выбрать все';
SelectAll.Tag:= 0;
end;
end;

procedure InitializeWizard();
var
I: Integer;
S: String;
begin
Page := CreateInputOptionPage(wpWelcome,
'Выберите компоненты', 'Какие компоненты хотите установить?',
'Выберите необходимые компоненты и нажмите далее.',
False, True);

SelectAll:= TButton.Create(WizardForm);
SelectAll.Width := WizardForm.BackButton.Width + ScaleX(10);
SelectAll.Height := WizardForm.BackButton.Height;
SelectAll.Top := WizardForm.BackButton.Top;
SelectAll.Left := WizardForm.BackButton.Left - WizardForm.BackButton.Width - ScaleX(40);
SelectAll.OnClick := @ButtonOnClick;
SelectAll.Parent := WizardForm;
SelectAll.Visible:= False;
SelectAll.Caption := 'Выбрать все';
SelectAll.Tag:= 0;

if RegGetValueNames(HKEY_CURRENT_USER, 'Software\My Program\Path', Names) then
begin
SetArrayLength(Value,GetArrayLength(Names));
for I := 0 to GetArrayLength(Names)-1 do
begin
RegQueryStringValue(HKEY_CURRENT_USER, 'Software\My Program\Path', Names[I], Value[I]);
Page.CheckListBox.AddCheckBox(Value[I], Names[I], 0, False, True, False, False, nil);
end;
end;
end;
Автор: omals
Дата сообщения: 29.12.2006 14:38

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

угу но токо я ешо для разных языков (если нужно конечно же) таки сделал бы:
Page := CreateInputOptionPage(wpWelcome,
ExpandConstant('{cm:WizardSelectComponents}'), ExpandConstant('{cm:SelectComponentsDesc}'),
ExpandConstant('{cm:SelectComponentsLabel2}'),
False, True);

ну или шото похожее
можно свои мессаги прописать для всех языков, а по дефолту брать какой определиш (ну на случай если для какогото яз1ка месаги не прописаны)
Автор: Genri
Дата сообщения: 29.12.2006 14:58
omals -- любую программу можно улучшать до бесконечности В скрипте у maxdddca123 все еще навороченней. Но я намеренно убрал оттуда некоторые фишки, чтобы акцентировать внимание на решении основной задачи (распаковать файлы в папки, кол-во которых и пути к ним, на этапе компиляции неизвестно).
Это только пример. Адаптация и тюнинг, это на усмотрение того, кто будет использовать.

Автор: omals
Дата сообщения: 29.12.2006 15:12
Genri

Цитата:
omals -- любую программу можно улучшать до бесконечности

согласен.
просто у меня почти все инсталяторы для множества языков - больная тема ...
потому и обратил внимание
Автор: maxdddca123
Дата сообщения: 29.12.2006 15:32
Genri

Цитата:
Но я намеренно убрал оттуда некоторые фишки

Какие это ты фишки убрал ?
Автор: Genri
Дата сообщения: 29.12.2006 15:45
maxdddca123
BeveledLabel, URLLabel, InitializeSetup, AboutButtonOnClick, BackgroundBitmapImage, BackgroundBitmapText, почти всю секцию [Setup] и все остальное, что не относилось к указанной задаче.
Надеюсь, финансовых претензий, ты мне предъявлять не собираешься?
Автор: maxdddca123
Дата сообщения: 29.12.2006 16:27
Genri

Цитата:
Надеюсь, финансовых претензий, ты мне предъявлять не собираешься?

Нет. Я вроде закончил со своим инсталлятором, надо конечно вылизать, но это после праздников. Земной поклон Вам, и с наступающими праздниками всех !!! До встречи в новом году. Сделаем самые крутые инсталляторы )))))))))))
Автор: NightW0lf
Дата сообщения: 30.12.2006 00:16
Привет всем!
Такой вопрос: на странице выбора директории установки приложения в инсталляторе созданном на Inno Setup 5.1.9 (да и других) при нажатии на кнопку обзор (browse) отсутствует кнопка "Создать папку"? А то получается, если надо установить в папку, которой вообще нет придется ее вручную прописывать чтобы она создалась (а это НЕ очень удабно)!

P.S.: Хотя в некоторых инсталляторах на Inno Setup 5.1.9 есть эта кнопка ("Создать папку") к примеру русификатор для "Warhammer - Mark of Chaos" с ZoneOfGames.ru.

Спасибо за внимание!
Автор: Genri
Дата сообщения: 30.12.2006 00:31
NightW0lf -- Из хелпа:
Цитата:
function BrowseForFolder(const Prompt: String; var Directory: String; const NewFolderButton: Boolean): Boolean;
Описание:
Отображает диалоговое окно, в котором пользователь может выбрать папку; первоначально будет выбрана папка, заданная в Directory. Если NewFolderButton=True, пользователь может создать новую папку. Возвращает True если пользователь выбрал папку, иначе False. Выбранная папка присваивается строковой переменной Directory.

Замечания:
Не все версии Windows поддерживают параметр NewFolderButton равный False и все равно его отображают.



Код:
procedure DirOnClick(Sender: TObject);
var
res: Boolean;
UserSelectDir: String;
begin
UserSelectDir:= WizardForm.DirEdit.Text;
res:= BrowseForFolder('Веберите папку для установки', UserSelectDir, True);
if res then
begin
WizardForm.DirEdit.Text:= UserSelectDir;
end;
end;

procedure InitializeWizard();
begin // эта строка в исходном сообщении была пропущена!!!
WizardForm.DirBrowseButton.OnClick:= @DirOnClick;
end;
Автор: NightW0lf
Дата сообщения: 30.12.2006 11:47
Genri
Что-то твой код не работает!

Код:
function BrowseForFolder(const Prompt: String; var Directory: String; const NewFolderButton: Boolean): Boolean;

procedure DirOnClick(Sender: TObject); //Здесь компилятор выдает ошибку!
var
res: Boolean;
UserSelectDir: String;
begin
UserSelectDir:= WizardForm.DirEdit.Text;
res:= BrowseForFolder('Веберите папку для установки', UserSelectDir, True);
if res then
begin
WizardForm.DirEdit.Text:= UserSelectDir;
end;
end;

procedure InitializeWizard();
WizardForm.DirBrowseButton.OnClick:= @DirOnClick;
end;
Автор: Genri
Дата сообщения: 30.12.2006 13:43
NightW0lf -- надеюсь, что строку:

function BrowseForFolder(const Prompt: String; var Directory: String; const NewFolderButton: Boolean): Boolean;

...ты в код не вставляешь ? В код надо вставлять только то, что ниже.
Автор: maxdddca123
Дата сообщения: 30.12.2006 14:06
NightW0lf
У меня работает !
Автор: NightW0lf
Дата сообщения: 30.12.2006 14:44
Genri
maxdddca123
Если я не использую строку:

Код:
function BrowseForFolder(const Prompt: String; var Directory: String; const NewFolderButton: Boolean): Boolean;
Автор: maxdddca123
Дата сообщения: 30.12.2006 14:58
NightW0lf
Какую ошибку то ?
Автор: NightW0lf
Дата сообщения: 30.12.2006 15:23
maxdddca123
Вот ошибка:
Line 68:
Column 3:
'BEGIN' expected.

P.S.: Помогите решь эту проблему все вроде правильно, НО у меня не работает!
Автор: maxdddca123
Дата сообщения: 30.12.2006 16:56
NightW0lf
Дак напиши BEGIN и ошибки не будет !!!

procedure InitializeWizard();
begin
WizardForm.DirBrowseButton.OnClick:= @DirOnClick;
end;
Автор: NightW0lf
Дата сообщения: 30.12.2006 17:11
maxdddca123

Цитата:
Дак напиши BEGIN и ошибки не будет !!!

procedure InitializeWizard();
begin
WizardForm.DirBrowseButton.OnClick:= @DirOnClick;
end;

Щас попробую!
А код я тебе в ПМ выслал!



Добавлено:
maxdddca123
БОЛЬШОЕ спасибо тебе ВСЕ теперь работает!
Теперь нужна помощь в следующем:
у меня почему-то из-за фоновой картинку в формате BMP или чего-то другова пропало форматирование у файла лицензии в формате ".rtf".
Автор: Chanka
Дата сообщения: 30.12.2006 17:52
Ребят, а как сделать, чтобы картинка не растягивалась, а находилась по-центру
Картинка размера 800х600

[Code]
procedure InitializeWizard();
var
BackgroundBitmapImage: TBitmapImage;
s:string;
begin
ExtractTemporaryFile('My_Image.bmp'); //My_Image.bmp - указываемое изображение в секции [Files]
s:=ExpandConstant('{tmp}')+'\My_Image.bmp';
BackgroundBitmapImage := TBitmapImage.Create(MainForm);
BackgroundBitmapImage.Bitmap.LoadFromFile(s);
BackgroundBitmapImage.Align := alClient;
BackgroundBitmapImage.Parent := MainForm;
BackgroundBitmapImage.Stretch:=True;
end;
Автор: maxdddca123
Дата сообщения: 30.12.2006 18:04
Genri
Как сделать кнопку неактивной ? Приведи пример пожалуйста.

Добавлено:
NightW0lf
Дак ты сам ртф файл пасмари... Помоему на форматирование скрипт не влияет.

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172

Предыдущая тема: ICONS


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