Вопрос Компоненты в Inno Setup

Darthame

Новичок
Здравствуйте. Мне нужна помощь в создании инсталлятора. На этом же форуме мне подсказали скрипт для вывода описания и превью компонентов через библиотеку botva2

Код:
#include "Modules\botva2.iss"

[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
OutputDir=.

[Files]
Source: Files\*; Flags: dontcopy

[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[CustomMessages]
russian.ComponentsName1=Моя программа™
russian.ComponentsName2=Помощь
russian.ComponentsName2_1=Документация
russian.ComponentsName2_2=Руководство пользователя
russian.ComponentsInfoPanel1=Описание
russian.ComponentsInfoPanel2=Наведите курсор мыши на компонент, чтобы прочитать его описание.
russian.ComponentsDescription1=Устанавливается обязательно
russian.ComponentsDescription2=Помощь
russian.ComponentsDescription3=Прочитать документацию
russian.ComponentsDescription4=Прочитать руководство пользователя

[Types]
Name: full; Description: Full installation; Flags: iscustom

[Components]
Name: text; Description: Язык субтитров; Types: full; Flags: fixed
Name: text\rus; Description: Русский; Flags: exclusive; ExtraDiskSpaceRequired: 100000000
Name: text\eng; Description: Английский; Flags: exclusive; ExtraDiskSpaceRequired: 200000000
Name: voice; Description: Язык озвучки; Types: full; Flags: fixed
Name: voice\rus; Description: Русский; Flags: exclusive; ExtraDiskSpaceRequired: 500000000
Name: voice\eng; Description: Английский; Flags: exclusive; ExtraDiskSpaceRequired: 600000000

[Code]
type
  TComponentDesc = record Description: String; Index: Integer; end;

var
  Descs: array of TComponentDesc;
  Info: TNewStaticText;
  InfoCaption: TNewStaticText;
  InfoPanel: TPanel;
  ImgPanel: TPanel;
  Indx: Integer;
  Img: array of Longint;

procedure ShowDescription(Sender: TObject; X, Y, Index: Integer; Area: TItemArea);
var i: Integer;
begin
  Indx:=-1;
  for i:= 0 to GetArrayLength(Descs)-1 do begin
  if (Descs[i].Index=Index) then begin Indx:=i; Break end; end;
  if (Indx >=0)and(Area=iaItem) then Info.Caption:= Descs[Indx].Description else Info.Caption:= ExpandConstant('{cm:ComponentsInfoPanel2}');
//
  ImgSetVisibility(Img[0],False);
  ImgSetVisibility(Img[1],False);
  ImgSetVisibility(Img[2],False);
  ImgPanel.Caption := 'Превью';
case Index of
  1: begin ImgPanel.Caption := ''; ImgSetVisibility(Img[0],True); end;
  2: begin ImgPanel.Caption := ''; ImgSetVisibility(Img[1],True); end;
  3: begin ImgPanel.Caption := ''; ImgSetVisibility(Img[2],True); end;
end;
  ImgApplyChanges(ImgPanel.Handle);
end;

procedure AddDescription(AIndex: Integer; ADescription: String);
var i, k: Integer;
begin
i:= GetArrayLength(Descs); SetArrayLength(Descs, i+1);
Descs[i].Description:= ADescription; Descs[i].Index:= AIndex-1
end;

function InitializeSetup:boolean;
begin
  if not FileExists(ExpandConstant('{tmp}\botva2.dll')) then ExtractTemporaryFile('botva2.dll');
  Result:=True;
end;

procedure ImgCreate(Filename: string; i: integer);
begin
  Img[i]:= ImgLoad(ImgPanel.Handle, Filename, 0, 0, ScaleX(200), ScaleY(181) - WizardForm.TypesCombo.Top, True,True);
  ImgSetVisibility(Img[i],False);
end;

procedure InitializeWizard();
begin
  WizardForm.TypesCombo.Visible:=False;
  WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Width := ScaleX(207);
  WizardForm.ComponentsList.OnItemMouseMove:= @ShowDescription

  ImgPanel := TPanel.Create(WizardForm);
  ImgPanel.Parent := WizardForm.SelectComponentsPage;
  ImgPanel.Caption := 'Превью';
  ImgPanel.Top := WizardForm.TypesCombo.Top;
  ImgPanel.Left := ScaleX(217);
  ImgPanel.Width := ScaleX(200);
  ImgPanel.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  ImgPanel.BevelInner := bvRaised;
  ImgPanel.BevelOuter := bvLowered;
//
  SetArrayLength(Img, WizardForm.ComponentsList.ItemCount);
//
  ImgCreate('1.jpg', 0);
  ImgCreate('2.jpg', 1);
  ImgCreate('3.jpg', 2);
//
  ImgApplyChanges(ImgPanel.Handle);

  InfoPanel := TPanel.Create(WizardForm);
  InfoPanel.Parent := WizardForm.SelectComponentsPage;
  InfoPanel.Caption := '';
  InfoPanel.Top := ScaleY(190);
  InfoPanel.Left := ScaleX(0);
  InfoPanel.Width := ScaleX(417);
  InfoPanel.Height := ScaleY(40);
  InfoPanel.BevelInner := bvRaised;
  InfoPanel.BevelOuter := bvLowered;
  InfoCaption := TNewStaticText.Create(WizardForm);
  InfoCaption.Parent := WizardForm.SelectComponentsPage;
  InfoCaption.Caption := ExpandConstant('{cm:ComponentsInfoPanel1}');
  InfoCaption.Left := ScaleX(7);
  InfoCaption.Top := InfoPanel.Top - ScaleY(6);
  InfoCaption.Font.Color := clActiveCaption;

  Info := TNewStaticText.Create(WizardForm);
  Info.Parent := InfoPanel;
  Info.AutoSize := False;
  Info.Left := ScaleX(6);
  Info.Width := ScaleX(403);
  Info.Top := ScaleY(12);
  Info.Height := ScaleY(24);
  Info.Caption := ExpandConstant('{cm:ComponentsInfoPanel2}');
  Info.WordWrap := true;

  AddDescription(1, 'Справка'); //первый параметр - это номер компонента, идет последовательно от начала записи компонентов
  AddDescription(2, 'Английская справка'); //Второй параметр - это собственно описание компонента
  AddDescription(3, 'Русская справка');
  AddDescription(4, 'Плагины');
  AddDescription(5, 'Внутреннего просмотра');
  AddDescription(6, 'Архиваторные');
  AddDescription(7, 'Системные');
  AddDescription(8, 'CanonCam');
  AddDescription(9, 'PluginManager');
  AddDescription(10, 'Registry');
  AddDescription(11, 'Services');
  AddDescription(12, 'StartupGuard');
  AddDescription(13, 'Другие');
end;

procedure DeinitializeSetup;
begin
  gdipShutDown;
end;

Можно ли прикрепить подобный скрипт для чекбоксов и радиокнопок, созданных на новой странице (через CreateCustomPage)? На этой странице должен быть CheckListBox, а в нем все чекбоксы и по наведению мыши инсталлятор должен выводить описание и показывать превью.

P.S. Хотелось бы еще увидеть, как устанавливать файлы, если чекбокс отмечен.
 

Nemko

Дилетант
Модератор
Darthame, здравствуйте. На счет примерного функционала вот (пример снизу), о по поводу установки, то нужно добавить условие.

Например для ISDone, выглядит как-то так:
Код:
    TmpValue:=1;
    if clbIsItemCheckedByIndex(ComponentList, 0) then Comps1:=Comps1+TmpValue; //компонент 1
    TmpValue:=TmpValue*2;
    ...
    if not IS7ZipExtract(1, 0, ExpandConstant('{src}\архив.7z'), ExpandConstant('{app}\'), False, '') then break;
А без ISDone, нужно например использовать параметр Check в секциях [Files] или [Components], а потом в секции [Сode] перебрать через оператор case of посланное сообщение и возвращать Boolean, в случае если выбран CheckBox.
 

Вложения

  • 88 KB Просмотры: 57
Последнее редактирование:

Darthame

Новичок
Darthame, здравствуйте. На счет примерного функционала вот (пример снизу), о по поводу установки, то нужно добавить условие.

А без ISDone, нужно например использовать параметр Check в секциях [Files] или [Components], а потом в секции [Сode] перебрать через оператор case of посланное сообщение и возвращать Boolean, в случае если выбран CheckBox.
Спасибо, то, что нужно. Но я в коде не очень разбираюсь. Как правильно написать этот скрипт?

Нашел где-то код, не уверен, что он правильный:
Код:
[Files]
Source: "Files\*"; DestDir: "{app}"; Check: IsChecked('Компонент_01');

function IsCompChecked(const CheckListBox: TNewCheckListBox; Name: String): Boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to CheckListBox.ItemCount - 1 do
begin
   Result := CheckListBox.Checked[I];
   if Result then
   Exit;
end;
end;

function IsChecked(Name: String): Boolean;
begin
Result := IsCompChecked(CheckListBox, Name);
end;
 

Nemko

Дилетант
Модератор
Darthame, похоже что да, пример правильный. Копирование директории последует, если CheckBox c именем 'Компонент_01' был отмечен.
 

Darthame

Новичок
Что-то не работает. После нажатия кнопки установить выделяется строка:
for I := 0 to CheckListBox.ItemCount - 1 do
с ошибкой Could not call proc.
 

sergey3695

Ветеран
Модератор
Darthame,
Код:
[Files]
Source: "Files\*"; DestDir: "{app}"; Check: IsChecked(1);
//...
function IsChecked(Index: integer): Boolean;
begin
  Result := clbIsItemCheckedByIndex(ComponentList, Index);
end;
и да, какой-то код не правильный и для TNewCheckListBox'a он.
этого было бы там достаточно.
Код:
 Result := NewCheckListBox1.Checked[NewCheckListBox1.Items.IndexOfName(Name)];
 
Последнее редактирование:

Romach

Новичок
Здравствуйте! Скажите пожалуйста как такое осуществить!?

c3ecba5dca2ff697efb552f221cd51da.png ?
 

Andreo Fadio

Старожил
Здравствуйте! Скажите пожалуйста как такое осуществить!?

Посмотреть вложение 4619 ?
Нужна расширенная версия Inno Setup от ResTool

и то что нужно добавить в секцию CODE:
Код:
procedure RedesignWizardForm;
begin
  with WizardForm.ComponentsList do
  begin
    TreeViewStyle := True;
  end;
end;

procedure InitializeWizard();
begin
  RedesignWizardForm;
end;
 

Romach

Новичок
Нужна расширенная версия Inno Setup от ResTool

и то что нужно добавить в секцию CODE:
Код:
procedure RedesignWizardForm;
begin
  with WizardForm.ComponentsList do
  begin
    TreeViewStyle := True;
  end;
end;

procedure InitializeWizard();
begin
  RedesignWizardForm;
end;
Спасибо ))) работает ))) , а возможно сделать так , чтоб по умолчанию они были спрятаны?
 

Nemko

Дилетант
Модератор
Romach, так (Flags: "Collapsed"):

Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={sd}\My Application

[Types]
Name: "Full"; Description: "Full"; Flags: "iscustom"
Name: "Custom"; Description: "Custom";

[Components]
Name: Tools; Description: "Tool"; Flags: "Collapsed"
Name: tool\1; Description: "??????";
Name: tool\2; Description: "??????";

Name: Plugins; Description: "Plug-ins"; Flags: "Collapsed"
Name: Plugin\1; Description: "??????";
Name: Plugin\2; Description: "??????";

Name: Codes; Description: "Source Code";
Name: Code\1; Description: "NSIS Source Code";
Name: Code\2; Description: "ExDLL Source(required)";
Name: Code\3; Description: "Zip2Exe Source";
Name: Code\4; Description: "T..."; Flags: "Collapsed"
Name: Code\4\Dop; Description: "??????";
Name: Code\4\Dop; Description: "??????";

[Code]
procedure ChangeType(Sender: TObject);
var
  i: Integer;
begin
with WizardForm do begin
  if Sender is TNewComboBox then begin
    if TypesCombo.ItemIndex = 0 then for i:=0 to ComponentsList.ItemCount-1 do ComponentsList.Checked[i]:=True
    else for i:=0 to ComponentsList.ItemCount-1 do ComponentsList.Checked[i]:=ComponentsList.Checked[i];
  end;
 end;
end;

procedure ChangeType2(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
begin
  WizardForm.TypesCombo.ItemIndex:=1;
end;


procedure InitializeWizard;
begin
with WizardForm do begin
  OuterNotebook.Hide;
  TypesCombo.OnChange:=@ChangeType;
  TypesCombo.Parent:=WizardForm;
  TypesCombo.SetBounds(ScaleX(180), ScaleY(115), ScaleX(300), ScaleY(23));
  ChangeType(TypesCombo);

  with ComponentsList do begin
    SetBounds(ScaleX(180), ScaleY(140), ScaleX(300), ScaleY(110));
    OnMouseDown:=@ChangeType2;
    TreeViewStyle:=True;
    Parent:=WizardForm;
  end;
 end
end;
 

Romach

Новичок
Romach, так (Flags: "Collapsed"):

Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={sd}\My Application

[Types]
Name: "Full"; Description: "Full"; Flags: "iscustom"
Name: "Custom"; Description: "Custom";

[Components]
Name: Tools; Description: "Tool"; Flags: "Collapsed"
Name: tool\1; Description: "??????";
Name: tool\2; Description: "??????";

Name: Plugins; Description: "Plug-ins"; Flags: "Collapsed"
Name: Plugin\1; Description: "??????";
Name: Plugin\2; Description: "??????";

Name: Codes; Description: "Source Code";
Name: Code\1; Description: "NSIS Source Code";
Name: Code\2; Description: "ExDLL Source(required)";
Name: Code\3; Description: "Zip2Exe Source";
Name: Code\4; Description: "T..."; Flags: "Collapsed"
Name: Code\4\Dop; Description: "??????";
Name: Code\4\Dop; Description: "??????";

[Code]
procedure ChangeType(Sender: TObject);
var
  i: Integer;
begin
with WizardForm do begin
  if Sender is TNewComboBox then begin
    if TypesCombo.ItemIndex = 0 then for i:=0 to ComponentsList.ItemCount-1 do ComponentsList.Checked[i]:=True
    else for i:=0 to ComponentsList.ItemCount-1 do ComponentsList.Checked[i]:=ComponentsList.Checked[i];
  end;
 end;
end;

procedure ChangeType2(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
begin
  WizardForm.TypesCombo.ItemIndex:=1;
end;


procedure InitializeWizard;
begin
with WizardForm do begin
  OuterNotebook.Hide;
  TypesCombo.OnChange:=@ChangeType;
  TypesCombo.Parent:=WizardForm;
  TypesCombo.SetBounds(ScaleX(180), ScaleY(115), ScaleX(300), ScaleY(23));
  ChangeType(TypesCombo);

  with ComponentsList do begin
    SetBounds(ScaleX(180), ScaleY(140), ScaleX(300), ScaleY(110));
    OnMouseDown:=@ChangeType2;
    TreeViewStyle:=True;
    Parent:=WizardForm;
  end;
 end
end;
Понял ))) огромное спасибо )))!!!!!!!!!!!!
 

Nemko

Дилетант
Модератор
Nikolay_96, сложно сказать наверняка, но если используется ISDone и подключаются компоненты, возможно дело в необходимости "Тестового прогона". FAQ прикреплю под спойлер, а так без кода сложно сказать, но думаю дело в этом или в подключении архивов...

  • Автоматическая расстановка процентных соотношений в операциях.
При автоматической расстановке необходим тестовый проход для определения времени выполнения каждой операции относительно других.
Для включения данного режима необходимо заполнить вторые значения всех функций извлечения архивов нулями.
Краткая инструкция:
а) первым делом убедитесь, что в начале скрипта закомментирована строка

#define records
(т.е. необходимо поставить точку с запятой в начале этой строки);
б) компилим проект и запускаем на установку. Это и будет нашим тестовым проходом. Все операции должны дойти до конца и завершиться удачно. Прогрессбар будет зашкаливать и все компоненты будут извлечены вне зависимости от того выбраны они, или нет. Все так и должно быть!
в) после тестового прогона в указанной папке создастся файл records.inf (имя и путь назначается в процедуре инициализации. О ней см. "подробное описание функций" ниже), его необходимо добавить в проект, раскомметировав, или добавив в начале скрипта строку:

#define records


Так же стоит отметить, что если сам скрипт находится в папке отличной от той, в которую компилится проект (например в скрипте NFS:Undercover откомпиленный файл сохраняется в Output\setup.exe), то records.inf создастся в папке с setup.exe и его необходимо будет перенести непосредственно к скрипту, или же подправить в секции [Files] его истинное расположение, например:

#ifdef records
Source: Output\records.inf; DestDir: {tmp}; Flags: dontcopy
#endif
г) снова откомпилить проект.
После этого инсталлер готов к работе.
При запуске процесс выполнения операций будет равномерно и корректно отображаться на прогрессбаре.
 

Nikolay_96

Новичок
Спасибо большое заработало беда была с тестовым прогоном как выяснилось.
 

Nikolay_96

Новичок
объясните,что нужно добавить в скрипт inno setup чтобы он распаковывал архивы precomp и srep.
 

Nemko

Дилетант
Модератор
Nikolay_96, выдержка из справки к ISDone Srep + Precomp:

Пример 1 : распаковка некоторой последовательности различных типов архивов. ISDoneError:=true;
if ISDoneInit(ExpandConstant('{src}\records.inf'), $F777, Comps1,Comps2,Comps3, MainForm.Handle, {#NeedMem}, @ProgressCallback) then begin
repeat
if not SrepInit('',512,0) then break;
if not PrecompInit('',128,0.4) then break;
if not FileSearchInit(false) then break;
if not IS7ZipExtract ( 0, 0, ExpandConstant('{src}\data64.7z'), ExpandConstant('{app}'), false, '' ) then break;
if not ISSRepExtract( 0, 0, ExpandConstant('{app}\data64a.srep'), ExpandConstant('{app}\data64.arc'), true ) then break;
if not ISArcExtract( 0, 0, ExpandConstant('{app}\data64.arc'), ExpandConstant('{app}\'), '', true, '', '', '',notPCFonFLY ) then break;
if not ISPrecompExtract( 0, 0, ExpandConstant('{app}\*.pcf'), ExpandConstant('{app}\'), true ) then break;
ISDoneError:=false;
until true;
ISDoneStop;
end;

Для начала инициализируем бибилиотеку командой ISDoneInit;
затем с помощью SrepInit инициализируем переменные для распаковки srep-архивов, задаем 512мб для менеджера памяти srep'а, остальные параметры оставляем по умолчанию;
далее с помощью PrecompInit инициализируем precomp для 0.4 версии;
и в FileSearchInit задаем, чтобы парсер входных имен архивов не сканировал все подкаталоги, если входным параметром была задана маска.

Дальше начинаеся непосредственно распаковка данных:
IS7ZipExtract распаковывает 7z-архив из {src}\data64.7z в {app};
потом ISSRepExtract извлекает {app}\data64a.srep в {app}\data64.arc удаляя исходный файл;
ISArcExtract извлекает data64.arc в {app}, удаляя исходный;
и ISPrecompExtract распаковывает все найденные .pcf файлы в {app}, удаляя исходные.
 
Последнее редактирование:

SBalykov

Старожил
Скорее всего, отсутствуют файлы для распаковки или закомментирован препроцессор.
Гадать можно сколько угодно...
Скрипт в студию!
 
Сверху