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

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

Автор: ComradG
Дата сообщения: 08.07.2008 22:45
Предположим, есть такой код
[_Code]
procedure LoadSkin(lpszPath: String; lpszIniFileName: String);
external 'LoadSkin@files:isskin.dll stdcall';

procedure UnloadSkin();
external 'UnloadSkin@files:isskin.dll stdcall';

function ShowWindow(hWnd: integer; uType: integer): integer;
external 'ShowWindow@user32.dll stdcall';

function InitializeSetup(): Boolean;
begin
ExtractTemporaryFile('Office2007.cjstyles');
LoadSkin(ExpandConstant('{tmp}\/*имя скина */'), '');
Result:=True;
end;

var
PageNameLabel, PageDescriptionLabel: TLabel;
procedure InitializeWizard();
begin
WizardForm.BorderStyle:=bsSingle;
WizardForm.BorderIcons:=[];
PageNameLabel := TLabel.Create(WizardForm);
with PageNameLabel do
begin
Left := ScaleX(10);
Top := ScaleY(10);
Width := ScaleX(300);
Height := ScaleY(14);
AutoSize := False;
WordWrap := True;
Font.Color := clBlack;
Font.Style := [fsBold];
ShowAccelChar := False;
Transparent := True;
Parent := WizardForm.MainPanel;
end;

PageDescriptionLabel := TLabel.Create(WizardForm);
with PageDescriptionLabel do
begin
Left := ScaleX(15);
Top := ScaleY(25);
Width := ScaleX(475);
Height := ScaleY(30);
AutoSize := False;
WordWrap := True;
Font.Color := clBlack;
ShowAccelChar := False;
Transparent := True;
Parent := WizardForm.MainPanel;
end;

with WizardForm do
begin
PageNameLabel.Hide;
PageDescriptionLabel.Hide;
with MainPanel do
begin
with WizardSmallBitmapImage do
begin
Left := ScaleX(0);
Top := ScaleY(0);
Width := Mainpanel.Width;
Height := MainPanel.Height;
end;
end;
end;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
PageNameLabel.Caption := WizardForm.PageNameLabel.Caption;
PageDescriptionLabel.Caption := WizardForm.PageDescriptionLabel.Caption;
end;

procedure DeinitializeSetup();
begin
ShowWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 0);
UnloadSkin();
end;
сам эксплойт описывать не буду, опишу баг. Во время деинсталляции сам скин не появляется. Если я юзаю через свою dll, то все пучком. А здесь чего не так?
Автор: Genri
Дата сообщения: 08.07.2008 23:23
ComradG

Цитата:
Если я юзаю через свою dll, то все пучком. А здесь чего не так?
-- здесь-то как-раз все так, как надо. Раз нет указания грузить скин при деинсталляции, то скин и не грузится. А вот при использовании "твоей dll", судя по тому, что ты описывал выше, в системе остается мусор, поэтому все и работает. Но, по хорошему, за собой чистить надо.
Почитай в хелпе раздел Pascal Scripting: Event Functions - разберешься.
Автор: SotM
Дата сообщения: 09.07.2008 08:19
ComradG
Есть такой интересный тэг в этом форуме [ more ]. Используй его по назначению.
Автор: SergeyLS
Дата сообщения: 09.07.2008 08:27
Здравствуйте!
Спасибо ExpeditorR


Цитата:

SergeyLS
Что-то я тоже не понял как удалить или заменить ключ, и поэтому написал следующий код:
procedure InitializeWizard();
var
i:integer;
st: TStringlist;
begin
st:=TStringlist;.create; // здесь наверно лишняя точка с запятой?
st.loadfromfile('c:\mp.ini');
for i:=0 to st.count-1 do
begin
if st.strings[i]='TeztMode=true' then
begin
st.Delete(i);
st.Insert(i,'TestMode=true');
end;
end;
st.savetofile('c:\mp.ini');
st.Free
end;
извращённо конечно, но работает Главное следи чтобы в искомой строчке (if st.strings[i]='TeztMode=true' then) регистр символов совпадал с теми, что в файле. И замени путь к файлу на свой.
Удачи!


Только мне помогло так:
procedure InitializeWizard();
begin
st:=TStringlist.create;
st.loadfromfile(strMyProgPath + '\Ini\mp.ini'); // strMyProgPath Раннее объявленная глобальная переменная (путь к папке установки)
for i:=0 to st.count-1 do
begin
if st.strings[i]='TeztMode=false' then
begin
st.Delete(i);
st.Insert(i,'TestMode=false');
end;
end;
st.savetofile(strMyProgPath + '\Ini\mp.ini');
st.Free
end;


К Genri

Цитата:

SergeyLS
Цитата:нужно в слове TeztMode заменить одну букву
-- не обязательно. Если речь идет об ини-файле, достаточно добавить правильный ключ (либо в секции [INI], либо через функцию SetIniBool в коде). В принципе этого достаточно (лишний ключ TeztMode на работоспособность не влияет). Но если хочешь совсем красиво, ключ TeztMode можно удалить функцией DeleteIniEntry.


TeztMode=false - лишний ключь, но TestMode=false - необходим, а если просто вставлять в секцию: Ini ключь TestMode=false, то остаются оба, что - не красиво.
А с функцией DeleteIniEntry - не разобрался (примеров не нашел), можно увидеть какой-нибудь примерчик?

Всего доброго, с уважением, Сергей.
Автор: Genri
Дата сообщения: 09.07.2008 09:24
SergeyLS --
Код:
[Setup]
AppName=My Program
AppVerName=My Program version 1.5
DefaultDirName={pf}\My Program

[INI]
Filename: "{app}\ini\mp.ini"; Section: "Options"; Key: "TestMode"; String: "true"; AfterInstall: DeleteIniKey('TeztMode')

[_Code]
procedure DeleteIniKey(KeyName: String);
begin
DeleteIniEntry('Options', KeyName, ExpandConstant('{app}\ini\mp.ini'));
end;
Автор: vserd
Дата сообщения: 09.07.2008 12:37
Всем доброго здравия.
Как в Inno можно сконвертировать бинарный GUID в строку?
Вот такой код:

Код:
type
HRESULT = Longint;

function CoCreateGuid (var pGUID : TGUID) : longint; external 'CoCreateGuid@OLE32.DLL stdcall';
function StringFromCLSID(const pGUID : TGUID; out P : Pchar): HRESULT; external 'StringFromCLSID@OLE32.DLL stdcall';
procedure CoTaskMemFree(var P:PChar); external 'CoTaskMemFree@OLE32.DLL stdcall';


function Succeeded(Status: HRESULT): BOOL;
begin
Result := Status and HRESULT($80000000) = 0;
end;

function GenGuiD : String;
var p1 :PChar; PGuid : TGuid;
lResult : longint;

begin
lResult := CoCreateGuid(PGUID); //<-- здесь получаем GUID
if Succeeded(StringFromCLSID(PGUID,p1))
then MsgBox('&#211;&#241;&#239;&#229;&#245;', mbError, MB_OK) <-- попадаем сюда, но p1 = ''
else MsgBox('&#237;&#229; &#243;&#228;&#224;&#247;&#224;', mbError, MB_OK);
Result := p1;
CoTaskMemFree(P1);
end;
Автор: nOobCrafter
Дата сообщения: 09.07.2008 14:05
2 Genri
Слушай, к тебе как то обращался человек "fty" по [more=поводу]
Возник вопрос по созданию резервной копии определенных файлов перед установкой.
....................................................................................
Нашел в старой ветке это:


Код: [Setup]
AppName=My Program
AppVerName=My Program version 1.5
DefaultDirName={pf}\My Program
Compression=lzma
SolidCompression=yes
Uninstallable=no

[Tasks]
Name: arc; Description: "Create backup"

[Files]
Source: Files\*.*; DestDir: {app}; BeforeInstall: CreateBackup

[_Code]
var
Page: TInputDirWizardPage;
ArcDir: String;

procedure CreateBackup();
var
SrcFile, DestFile: string;
begin
if IsTaskSelected('arc') then
begin
// if Not DirExists(ArcDir) then CreateDir(ArcDir);
ForceDirectories(ArcDir); // исправлено
SrcFile:= AddBackslash(ExpandConstant('{app}')) + ExtractFileName(CurrentFileName);
DestFile:= AddBackslash(ArcDir) + ExtractFileName(CurrentFileName);
FileCopy(SrcFile, DestFile, False);
end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
If (CurPageID = Page.ID) then
ArcDir := Page.Values[0];
Result:= True;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
If (PageID = Page.ID) and
(Not IsTaskSelected('arc')) then
Result:= True
else Result:= False;
end;

procedure InitializeWizard();
begin
Page:= CreateInputDirPage(wpSelectTasks, 'Select Backup Location',
'Where should backup files be stored?',
'To continue, click Next.' + #10#13#10#13 +
'If you would like to select a different folder, click Browse.',
False, 'Backup');
Page.Add('');
//Page.Values[0] := ExpandConstant('{sd}\Backup');
Page.Values[0] := AddBackslash(ExpandConstant('{sd}\Backup'));
end;
Автор: Genri
Дата сообщения: 09.07.2008 16:26
vserd -- насколько я понимаю, проблема в том, что в StringFromCLSID второй параметр должен быть не указателем на Char (т.е. PChar), а указателем на указатель на строку.
Может проще будет использовать не StringFromCLSID, а StringFromGUID2 ?
И еще: надеюсь TGUID у тебя объявлен правильно? В твоем примере его нет. Должно быть как-то так:
type
TGUID = record
D1: Longword;
D2: Word;
D3: Word;
D4: array[0..7] of Byte;
end;

Будет возможность, попробую сообразить пример. [more=Пример]
[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program

[_Code]
type
HRESULT = Longint;

TGUID = record
D1: Longword;
D2: Word;
D3: Word;
D4: array[0..7] of Byte;
end;

function CoCreateGuid (var pGUID : TGUID) : longint; external 'CoCreateGuid@OLE32.DLL stdcall';
function StringFromGUID2(const pGUID : TGUID; str : string; cchMax : integer): HRESULT; external 'StringFromGUID2@OLE32.DLL stdcall';

function Succeeded(Status: HRESULT): BOOL;
begin
Result := Status and HRESULT($80000000) = 0;
end;

function GenGuiD : String;
var
str: string;
PGUID : TGuid;
lResult : longint;
begin
str:= StringOfChar(#0, 75+1);
lResult := CoCreateGuid(PGUID);
lResult:= StringFromGUID2(PGUID, str, Length(str));
if Succeeded(lResult)
then
begin
StringChangeEx(str, #0, '', True);
MsgBox('GUID: ' + str, mbError, MB_OK)
end
else MsgBox('Error', mbError, MB_OK);
end;

procedure InitializeWizard();
begin
GenGuiD;
end; [/more]
Автор: SergeyLS
Дата сообщения: 09.07.2008 17:45
Приветствую!
Genri
Писал:

Цитата:

SergeyLS --
Код:
[Setup]
AppName=My Program
AppVerName=My Program version 1.5
DefaultDirName={pf}\My Program

[INI]
Filename: "{app}\ini\mp.ini"; Section: "Options"; Key: "TestMode"; String: "true"; AfterInstall: DeleteIniKey('TeztMode')

[_Code]
procedure DeleteIniKey(KeyName: String);
begin
DeleteIniEntry('Options', KeyName, ExpandConstant('{app}\ini\mp.ini'));
end;

У меня данный метод не срабатыват, точнее дописывается
[[Options]]
TestMode=false
В конец файла с двумя скобкам, а нужно в ту же позицию и с одной парой скобок.
Всего доброго, с уважением, Сергей.
Автор: Genri
Дата сообщения: 09.07.2008 17:54
SergeyLS -- проверь синтаксис. Возможно у тебя лишние скобки:
Filename: "{app}\ini\mp.ini"; Section: "[Options]"; Key: "TestMode"; String: "true"; AfterInstall: DeleteIniKey('TeztMode')

... а надо:
Filename: "{app}\ini\mp.ini"; Section: "Options"; Key: "TestMode"; String: "true"; AfterInstall: DeleteIniKey('TeztMode')

Добавлено:
На будущее, желательно не цитировать предложенный вариант, а выкладывать свой кусок скрипта. Тогда не придется гадать. И еще:

Цитата:
Всего доброго, с уважением, Сергей.
-- на мой взгляд, это лишнее. Не в плане совета перечитать п.1.9 VIII.раздела правил форума, а по причине, что это немного смущает (ощущение, что ты прощаешься всерьез и надолго)
Автор: shurman31
Дата сообщения: 09.07.2008 21:49
Здравствуйте!! Не подскажите такая проблема, при создании установочного файла через мастера, при добавлении папок, на вопрос включать поддиректории отвечаю Да. Но при установке папки устанавливаются нре в такой иерархии, а поддиректории вылазеют в корневую.

Не подскажите из-за чего такое может быть???
Автор: blaster4
Дата сообщения: 09.07.2008 23:13
Огромное спасибо !!! ExpeditorR

Но получилось немного не то, в файл пишет что надо, но изменяет имя файла fl.ini на SecretsOfAlamutfl.ini и сохраняет его прямо на диск C. Возможно я не полностью объяснил смысл. Попробую еще раз.
Файл fl.ini находится в директории игры "SecretsOfAlamut",но вовремя установки игры пользователь может изменить директорию установки и игра не запустится так, как считывает параметры для запуска из fl.ini.
Нужно чтобы во время установки в строку CDPATH: прописывался полный путь установки или строка заново!
Пожалуйста помоги разобраться нужной информации про запись и изменение ini файлов я ненашел

Файл fl.ini
17
CDPATH: C:\SecretsOfAlamut
LANGUAGE:     RUS
CHECKCD:     1
SOUNDCHUNCK_BGRMUS: 9
LOADFROM_BGRMUS: 2
SOUNDCHUNCK_AMBMUS: 9
LOADFROM_AMBMUS: 2    
SOUNDCHUNCK_AMBEFE: 9
LOADFROM_AMBEFE: 2
SOUNDCHUNCK_EFE: 9
LOADFROM_EFE: 2
SOUNDCHUNCK_DIA: 9
LOADFROM_DIA: 2
ART_BAG: 1
ART_CURSOR: 1
ART_SY: 1
CHECKLOADSAVE:     0
Автор: Genri
Дата сообщения: 09.07.2008 23:34
nOobCrafter -- по поводу бэкапа: из твоего вопроса, я не совсем понял задачи. Если надо забэкапить целиком C:\123 в C:\123_old, то почему не подходит указанный тобой вариант? Ставь эту строку первой, и выполнится сначала бэкап, а потом пойдет инсталляция других файлов.
Автор: ExpeditorR
Дата сообщения: 10.07.2008 08:11
blaster4
Тогда сделай так:

procedure DeinitializeSetup();
var
s:tstringlist;
begin
try
s:=tstringlist.create;
s.add('17');
s.add('CDPATH: '+ExpandConstant('{app}'));
s.add('LANGUAGE: RUS');
s.add('CHECKCD: 1');
s.add('SOUNDCHUNCK_BGRMUS: 9');
s.add('LOADFROM_BGRMUS: 2');
s.add('SOUNDCHUNCK_AMBMUS: 9');
s.add('LOADFROM_AMBMUS: 2');
s.add('SOUNDCHUNCK_AMBEFE: 9');
s.add('LOADFROM_AMBEFE: 2');
s.add('SOUNDCHUNCK_EFE: 9');
s.add('LOADFROM_EFE: 2');
s.add('SOUNDCHUNCK_DIA: 9');
s.add('LOADFROM_DIA: 2');
s.add('ART_BAG: 1');
s.add('ART_CURSOR: 1');
s.add('ART_SY: 1');
s.add('CHECKLOADSAVE: 0');
s.savetofile(ExpandConstant('{app}\fl.ini'));
except
end;
end;

Данный код полностью создаст новый файл fl.ini в папке с игрой. Если нужно ещё какие-то строчки добавить то действуй по аналогии.
Кстати забудь про работу с ini файлами, так как твой файл имеет структуру обычного текстового файла.
P.S.
Попробуй в строке CHECKCD: 1 поставить 0, возможно не будет просить диск с игрой.
Автор: nOobCrafter
Дата сообщения: 10.07.2008 08:27
2 Genri Ставил, неработает, а неработает потому что уже во время установки данной папки уже несуществует, у меня идет ее бэкап через простое переименовывание. То есть, если бэкап идет как я и хотел до инстала то все орм по действиям но как и у человека копируется лишь структура ПАПОК нужной директории, а самих файлов в них нету что странно. а если писать через строку [Files] то к тому времени просто неоткуда копировать. Буду на работе выложу код, просто пока что дома.
Автор: SergeyLS
Дата сообщения: 10.07.2008 09:06
Приветствую!
Genri написал:

Цитата:
SergeyLS -- проверь синтаксис. Возможно у тебя лишние скобки:
Filename: "{app}\ini\mp.ini"; Section: "[Options]"; Key: "TestMode"; String: "true"; AfterInstall: DeleteIniKey('TeztMode')

Спасибо, был вчера невнимательным, оставил старую секцию:
Filename: {app}\Ini\mp.ini; Section: [Game]; Key: TestMode; String: true
Просто дописав к ней: AfterInstall: DeleteIniKey('TeztMode')
А там - была изначальная ошибка, которую я раньше - просто не замечал.

Цитата:

Добавлено:
На будущее, желательно не цитировать предложенный вариант, а выкладывать свой кусок скрипта. Тогда не придется гадать.

Ок. Учту!

Цитата:

И еще:

Цитата:Всего доброго, с уважением, Сергей.
-- на мой взгляд, это лишнее. Не в плане совета перечитать п.1.9 VIII.раздела правил форума, а по причине, что это немного смущает (ощущение, что ты прощаешься всерьез и надолго)

Ладно, действительно не подумал.
Еще раз огромное спасибо всем откликнувшимся!
Пока!
Автор: ExpeditorR
Дата сообщения: 10.07.2008 10:15
shurman31
Покажи сгенерированный мастером код, тогда можно будет понять в чём дело, и подсказать.
Автор: chum2000
Дата сообщения: 10.07.2008 11:13
Подскажите пожалуйста, как решить такую задачку?
На странице заданий добавляю две радио кнопки: "для всех" и "для себя". Суть понятна - создавать значки и делать записи в реестре.
Если выбирается "для всех", то запись в реестр должна делаться в HKLM, а "для себя" - HKCU.
Можно ли каким-либо образом управлять такими записями в секции [Registry] или только в коде?
Автор: vserd
Дата сообщения: 10.07.2008 11:29
Genri
ОГРОМНОЕ СПАСИБО!!!!
Автор: Genri
Дата сообщения: 10.07.2008 11:32
chum2000 -- в общем случае, можно только через секцию [Registry]. Создаешь две записи - для HKLM и HKCU, и каждой выставляешь соответствующий параметр Tasks.
Автор: cepbl4
Дата сообщения: 10.07.2008 11:45
Привет всем!

Осваиваю Inno setup уже давно, но только сейчас решил поработать с блоком Code

Сделал простой инсталл игры: файлы, пару параметров реестра, значки.., и решил замутить фоновую картинку bmp и наложил новые текстуры на кнопки. После долгих чертыханий по поводу неумения соединить 2 кода для вышеперечисленного из Руководства по расширенным возможностям Inno Setup 5.1 (не для чайников) от Kindly, все-таки соединил и вроде бы все заработало, скомпилил инсталл, запускаю, по умолчанию папка ц:\гамес, а там не хватает места для моей игрушки, вылазит окно, ругается на недостаток места, нажимаю продолжить -> Да (Нет тоже пробовал та же фигня) и кнопка Далее становится зажатой (в моем случае оранжевой, а ненажатая - синяя) на всех остальных окнах, если нажать Назад, кнопка Далее приобретает нормальный для себя синий цвет.

Помогите, plz, Инно-Гуру

Код:
[more]const
ButtonWidth = 80; //Указываем размер кнопок
ButtonHeight = 23;

bidBack = 0;
bidNext = 1;
bidCancel = 2;
bidDirBrowse = 3;
bidGroupBrowse = 4;

var
ButtonPanel: array [0..4] of TPanel;
ButtonImage: array [0..4] of TBitmapImage;
ButtonLabel: array [0..4] of TLabel;

procedure ButtonLabelClick(Sender: TObject);
var
Button: TButton;
begin
ButtonImage[TLabel(Sender).Tag].Left:=0
case TLabel(Sender).Tag of
bidBack: Button:=WizardForm.BackButton
bidNext: Button:=WizardForm.NextButton
bidCancel: Button:=WizardForm.CancelButton
bidDirBrowse: Button:=WizardForm.DirBrowseButton
bidGroupBrowse: Button:=WizardForm.GroupBrowseButton
else
Exit
end
Button.OnClick(Button)
end;

procedure ButtonLabelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if ButtonLabel[TLabel(Sender).Tag].Enabled then
ButtonImage[TLabel(Sender).Tag].Left:=-ButtonWidth
end;

procedure ButtonLabelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
ButtonImage[TLabel(Sender).Tag].Left:=0
end;

procedure LoadButtonImage(AButton: TButton; AButtonIndex: integer);
var
Image: TBitmapImage;
Panel: TPanel;
Labl: TLabel;

begin
Panel:=TPanel.Create(WizardForm)
Panel.Left:=AButton.Left
Panel.Top:=AButton.Top
Panel.Width:=AButton.Width
Panel.Height:=AButton.Height
Panel.Tag:=AButtonIndex
Panel.Parent:=AButton.Parent
ButtonPanel[AButtonIndex]:=Panel

Image:=TBitmapImage.Create(WizardForm) //Рисунок который ложится на кнопку
Image.Width:=160 //Обязательно прописать оригинальный размер рисунка
Image.Height:=23
Image.Enabled:=False
Image.Bitmap.LoadFromFile(ExpandConstant('{tmp}\button.bmp'))
Image.Parent:=Panel
ButtonImage[AButtonIndex]:=Image

with TLabel.Create(WizardForm) do begin
Tag:=AButtonIndex
Parent:=Panel
Width:=Panel.Width
Height:=Panel.Height
Transparent:=True
OnClick:=@ButtonLabelClick
OnDblClick:=@ButtonLabelClick
OnMouseDown:=@ButtonLabelMouseDown
OnMouseUp:=@ButtonLabelMouseUp
end

Labl:=TLabel.Create(WizardForm) //Текст кнопок
Labl.Left:=23 //Указываем положение текста
Labl.Top:=5
Labl.Autosize:=True
Labl.Alignment:=taCenter
Labl.Tag:=AButtonIndex
Labl.Transparent:=True
Labl.Font.Color:=clWhite //Цвет текста
Labl.Caption:=AButton.Caption
Labl.OnClick:=@ButtonLabelClick
Labl.OnDblClick:=@ButtonLabelClick
Labl.OnMouseDown:=@ButtonLabelMouseDown
Labl.OnMouseUp:=@ButtonLabelMouseUp
Labl.Parent:=Panel
ButtonLabel[AButtonIndex]:=Labl
end;

procedure UpdateButton(AButton: TButton;AButtonIndex: integer);
begin
ButtonLabel[AButtonIndex].Caption:=AButton.Caption
ButtonPanel[AButtonIndex].Visible:=AButton.Visible
ButtonLabel[AButtonIndex].Enabled:=Abutton.Enabled
end;

procedure LicenceAcceptedRadioOnClick(Sender: TObject);
begin
ButtonLabel[bidNext].Enabled:=True
end;

procedure LicenceNotAcceptedRadioOnClick(Sender: TObject);
begin
ButtonLabel[bidNext].Enabled:=False
end;

procedure CurPageChanged(CurPageID: Integer);
begin
UpdateButton(WizardForm.BackButton,bidBack)
UpdateButton(WizardForm.NextButton,bidNext)
UpdateButton(WizardForm.CancelButton,bidCancel)
end;
function GetSystemMetrics(nIndex:Integer):Integer;
external 'GetSystemMetrics@user32.dll stdcall';
var
width,height: Integer;
BackgroundBitmapImage: TBitmapImage;
s: string;

procedure InitializeWizard();
begin
WizardForm.BackButton.Width:=ButtonWidth
WizardForm.BackButton.Height:=ButtonHeight

WizardForm.NextButton.Width:=ButtonWidth
WizardForm.NextButton.Height:=ButtonHeight

WizardForm.CancelButton.Width:=ButtonWidth
WizardForm.CancelButton.Height:=ButtonHeight

WizardForm.DirBrowseButton.Left:=337
WizardForm.DirBrowseButton.Width:=ButtonWidth
WizardForm.DirBrowseButton.Height:=ButtonHeight

WizardForm.GroupBrowseButton.Left:=337
WizardForm.GroupBrowseButton.Width:=ButtonWidth
WizardForm.GroupBrowseButton.Height:=ButtonHeight

WizardForm.LicenseAcceptedRadio.OnClick:=@LicenceAcceptedRadioOnClick

WizardForm.LicenseNotAcceptedRadio.OnClick:=@LicenceNotAcceptedRadioOnClick

ExtractTemporaryFile('button.bmp')
LoadButtonImage(WizardForm.BackButton,bidBack)
LoadButtonImage(WizardForm.NextButton,bidNext)
LoadButtonImage(WizardForm.CancelButton,bidCancel)
LoadButtonImage(WizardForm.DirBrowseButton,bidDirBrowse)
LoadButtonImage(WizardForm.GroupBrowseButton,bidGroupBrowse)
ExtractTemporaryFile('background.bmp');
s:=ExpandConstant('{tmp}')+'\background.bmp';
WizardForm.Position:=poScreenCenter;
MainForm.BORDERSTYLE:=bsNone;
width:=GetSystemMetrics(0);
height:=GetSystemMetrics(1);
MainForm.Width:=width;
MainForm.Height:=height;
width:=MainForm.ClientWidth;
height:=MainForm.ClientHeight;
MainForm.Left := 0;
MainForm.Top := 0;
BackgroundBitmapImage := TBitmapImage.Create(MainForm);
BackgroundBitmapImage.Bitmap.LoadFromFile(s);
BackgroundBitmapImage.Align := alClient;
BackgroundBitmapImage.Parent := MainForm;
BackgroundBitmapImage.Stretch:=True;
MainForm.Visible:=True;
WizardForm.BorderStyle := bsSingle;
end;[/more]

Еще вопросы:
Если WizardSmallImageFile больше, чем 55х55 пикселей, как сделать так, чтобы картинка отображалась полностью по ширине?

как сделать так, чтобы на последнем экране можно было выбирать из того, что запускать, из нескольких пунктов только один (типа flag exclusive)
Автор: nOobCrafter
Дата сообщения: 10.07.2008 12:17
Вот пример [more=кода][Setup]
AppName=My Program
AppVerName=My Program v.1.2
DirExistsWarning=no
DefaultDirName=C:\innosetup\output\2
DisableStartupPrompt=true
Compression=bzip
Uninstallable=true
DisableProgramGroupPage=true
OutputBaseFilename=пример123

[Files]
Source: "compiler:Examples\MyProg.exe"; DestDir: {app}; BeforeInstall: CreateBackup;

[Tasks]
Name: arc; Description: "Create backup"

[Code]
var
Page: TInputDirWizardPage;
ArcDir: String;

procedure CreateBackup();
var
SrcFile, DestFile: string;
begin
if IsTaskSelected('arc') then
begin
// if Not DirExists(ArcDir) then CreateDir(ArcDir);
ForceDirectories(ArcDir); // исправлено
SrcFile:= AddBackslash(ExpandConstant('{app}\123')) + ExtractFileName(CurrentFileName);
DestFile:= AddBackslash(ArcDir) + ExtractFileName(CurrentFileName);
FileCopy(SrcFile, DestFile, False);
end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
If (CurPageID = Page.ID) then
ArcDir := Page.Values[0];
Result:= True;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
If (PageID = Page.ID) and
(Not IsTaskSelected('arc')) then
Result:= True
else Result:= False;
end;

procedure InitializeWizard();
begin
Page:= CreateInputDirPage(wpSelectTasks, 'Select Backup Location',
'Where should backup files be stored?',
'To continue, click Next.' + #10#13#10#13 +
'If you would like to select a different folder, click Browse.',
False, 'Backup');
Page.Add('');
//Page.Values[0] := ExpandConstant('{sd}\Backup');
Page.Values[0] := AddBackslash(ExpandConstant('{sd}\Backup')); // исправлено
end;
type
TSHFileOpStruct = record
Wnd: HWND;
wFunc: UINT;
pFrom: PChar;
pTo: PChar;
fFlags: Word;
fAnyOperationsAborted: BOOL;
hNameMappings: HWND;
end;

const
FO_RENAME = $0004;
FOF_FILESONLY = $0080;
FOF_ALLOWUNDO = $0040;
FOF_SILENT = $0004;
FOF_NOCONFIRMATION = $0010;
FO_MOVE = $0001;
FO_COPY = $0002;
FO_DELETE = $0003;

function SHFileOperation(const lpFileOp: TSHFileOpStruct):Integer;
external 'SHFileOperation@shell32.dll stdcall';

function RenameDir(const fromDir, toDir: string): Boolean;
var
fos: TSHFileOpStruct;
_fromDir, _toDir: string;
begin
_fromDir:= RemoveBackslashUnlessRoot(fromDir) + #0#0;
_toDir := RemoveBackslashUnlessRoot(toDir) + #0#0;
fos.wFunc := FO_RENAME;
fos.fFlags := FOF_FILESONLY or FOF_ALLOWUNDO or
FOF_SILENT or FOF_NOCONFIRMATION;
fos.pFrom := PChar(_fromDir);
fos.pTo := PChar(_toDir);
Result := (0 = ShFileOperation(fos));
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
if DirExists(ExpandConstant('{app}')) then
begin
RenameDir(ExpandConstant('{app}'), ExpandConstant('{app}' + ' -' + GetDateTimeString('dd/mm/yyyy hh:nn:ss ', '-', '-') + '\'));
end;
end;
end;[/more]
То есть нам надо сделать 2 вещи:
1. Бэкап всей папки программы с уникальным именем что бы при повторной перестановке (бэкапе) файлы не затирались. Это есть.
2. Копирование дочерней папки с настройками для последующего преобразования допустим.

Поскольку имя бэкапа главное папки уникально, то к нему мы никак привязаться неможем, и как вариант, надо сделать копию нужной папки до переименования. Но проблема в том что при таком коде получается, что файлы из этой папки неберутся, зато вся структура папок сохраняется в папке бэкапа ( то есть копирует только пустые папки %) в чем дело непойму.
З.Ы. в коде я не делал папку "123" но считаем что она есть, просто пути и файлы изменены.. мне важно понять смысл.
Автор: Genri
Дата сообщения: 10.07.2008 14:33
nOobCrafter -- не совсем понятно, что такое "дочерняя папка". Вложенная? Вложенная в ту, которая переименовывается? В любом случае, кроме функции RenameDir, из файла SHFileOperation.iss можешь взять еще и функцию BackupDir и вызывай ее когда тебе надо. Хотя при желании, в обоих случаях можно использовать функцию BackupDir (собственно, для этого она и делалась).
Т.е. если я тебя правильно понял:
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
if DirExists(ExpandConstant('{app}')) then
begin
BackupDir(ExpandConstant('{app}\123'), 'C:\123_old', False);
RenameDir(ExpandConstant('{app}'), ExpandConstant('{app}' + ' -' + GetDateTimeString('dd/mm/yyyy hh:nn:ss ', '-', '-') + '\'));
end;
end;
end;

И кстати, почему это мы не можем привязаться к уникальному имени папки, раз мы сами это уникальное имя и задаем? Сохрани созданное имя в переменную и используй там где необходимо.
Автор: Sandy Ann
Дата сообщения: 11.07.2008 02:23
Подскажите:
1 Как в секцию Setup прописать переменную, содержимое которой будет зависить от языка установки?
2 Как сохранить стиль деинсталлятора, при использовании ISSkin.dll, используя [more=скрипт][Files]
Source: ISSkin.dll; DestDir: {app}; Flags: dontcopy
Source: Office2007.cjstyles; DestDir: {tmp}; Flags: dontcopy

[Code]
// Importing LoadSkin API from ISSkin.DLL
procedure LoadSkin(lpszPath: String; lpszIniFileName: String);
external 'LoadSkin@files:isskin.dll stdcall';

// Importing UnloadSkin API from ISSkin.DLL
procedure UnloadSkin();
external 'UnloadSkin@files:isskin.dll stdcall';

// Importing ShowWindow Windows API from User32.DLL
function ShowWindow(hWnd: Integer; uType: Integer): Integer;
external 'ShowWindow@user32.dll stdcall';

function InitializeSetup(): Boolean;
begin
    ExtractTemporaryFile('Office2007.cjstyles');
    LoadSkin(ExpandConstant('{tmp}\Office2007.cjstyles'), 'NormalBlack.ini');
    Result := True;
end;

procedure DeinitializeSetup();
begin
    // Hide Window before unloading skin so user does not get
    // a glimse of an unskinned window before it is closed.
    ShowWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 0);
    UnloadSkin();
end;[/more] из ISSkin Visual Styles?
Заранее спасибо
Автор: chum2000
Дата сообщения: 11.07.2008 08:05
Genri

Цитата:
chum2000 -- в общем случае, можно только через секцию [Registry]. Создаешь две записи - для HKLM и HKCU, и каждой выставляешь соответствующий параметр Tasks.

Я это прекрасно понимаю, но тогда они появятся на странице выбора задания. Можно ли их как-то скрыть? Просто на ней есть другие задания для выбора.
Автор: nOobCrafter
Дата сообщения: 11.07.2008 09:52
Genri Я просто недорос до таких тонкостей как ты написал, потому и казалось что невозможно %)
А функцию бэкапа мне актуально использовать лишь 1 раз, при копированиипапки с настройками, а основную папку проще переименовать, и не тратить время на отдельную ее копию, ведь при переустановке все файлы обновятся.
Спасибо.
Автор: Genri
Дата сообщения: 11.07.2008 11:38
chum2000

Цитата:
но тогда они появятся на странице выбора задания. Можно ли их как-то скрыть? Просто на ней есть другие задания для выбора.
-- кого "их"?? Ты же писал:

Цитата:
На странице заданий добавляю две радио кнопки: "для всех" и "для себя". Суть понятна - создавать значки и делать записи в реестре.
Если выбирается "для всех", то запись в реестр должна делаться в HKLM, а "для себя" - HKCU.
-- т.е. радио-кнопки должны быть видны, выбирает одну из них пользователь. Так? Так что надо скрывать? И другие задания на это никак не влияют.
На всякий случай - [more=простейший пример]
[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program

[Tasks]
Name: reg; Description: "Create a &registry"; GroupDescription: "Additional icons:"
Name: reg\common; Description: "For all users"; GroupDescription: "Registry for all:"; Flags: exclusive
Name: reg\user; Description: "For the current user only"; GroupDescription: "Registry for current user only:"; Flags: exclusive unchecked
Name: quicklaunchicon; Description: "Create a &Quick Launch icon"; GroupDescription: "Additional icons:"; Flags: unchecked
Name: associate; Description: "&Associate files"; GroupDescription: "Other tasks:"; Flags: unchecked

[Registry]
Root: HKCU; Subkey: "Software\My Company\My Program"; Flags: uninsdeletekey; Tasks: reg\user
Root: HKLM; Subkey: "Software\My Company\My Program"; Flags: uninsdeletekey; Tasks: reg\common
[/more]. Запись в реестр идет либо в HKCU, либо в HKLM (в зависимости от выбора пользователя).

nOobCrafter -- не информативный ответ Не понятно, вопрос решен или нет?
И кстати, в функции BackupDir последний параметр определяет, будет осуществлятся копирование или перемещение. А перемещение - это и есть по сути переименование
Автор: nOobCrafter
Дата сообщения: 11.07.2008 14:56
ДДдааа, чем дальше в лес тем более знаешь) Спс все так как надо. Теперь попробую всеэто дело совместить))))
Гхым.. захотел сделать что бы [more=все это дело срабатывало по галочке (таску)][Files]
Source: "compiler:Examples\MyProg.exe"; DestDir: {app}; BeforeInstall: CreateBackup

[Tasks]
Name: arc; Description: "Create backup"

[Code]
var
ArcDir: String;

type
TSHFileOpStruct = record
Wnd: HWND;
wFunc: UINT;
pFrom: PChar;
pTo: PChar;
fFlags: Word; // FILEOP_FLAGS;
fAnyOperationsAborted: BOOL;
hNameMappings: HWND; // Pointer;
lpszProgressTitle: PChar; { only used if FOF_SIMPLEPROGRESS }
end;

const

FO_MOVE = $0001;
FO_COPY = $0002;
FO_DELETE = $0003;
FO_RENAME = $0004;
FOF_MULTIDESTFILES = $0001;
FOF_CONFIRMMOUSE = $0002;
FOF_SILENT = $0004;
FOF_RENAMEONCOLLISION = $0008;
FOF_NOCONFIRMATION = $0010;
FOF_WANTMAPPINGHANDLE = $0020;
FOF_ALLOWUNDO = $0040;
FOF_FILESONLY = $0080;
FOF_SIMPLEPROGRESS = $0100;
FOF_NOCONFIRMMKDIR = $0200;
FOF_NOERRORUI = $0400;


function SHFileOperation(const lpFileOp: TSHFileOpStruct):Integer;
external 'SHFileOperation@shell32.dll stdcall';

function BackupDir(const fromDir, toDir: string; IsMove: Boolean): Boolean;
var
fos: TSHFileOpStruct;
_fromDir, _toDir: string;
SR: TFindRec;
res: Boolean;
begin
ForceDirectories(toDir);
if IsMove then
fos.wFunc := FO_MOVE else
fos.wFunc := FO_COPY;
fos.fFlags := FOF_FILESONLY or FOF_SILENT or
FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;
_fromDir:= AddBackslash(fromDir);
_toDir := AddBackslash(toDir);
if (Length(fromDir) = Length(_fromDir)) then
begin
res:= FindFirst(_fromDir + '*', SR);
try
while res do
begin
if (SR.Name <> '') and (SR.Name <> '.') and (SR.Name <> '..') then
begin
if SR.Attributes = FILE_ATTRIBUTE_DIRECTORY then
begin
_fromDir:= _fromDir + SR.Name + #0#0;
_toDir := _toDir + #0#0;
fos.pFrom := PChar(_fromDir);
fos.pTo := PChar(_toDir);
end else
begin
_fromDir:= _fromDir + SR.Name + #0#0;
_toDir := _toDir + SR.Name + #0#0;
fos.pFrom := PChar(_fromDir);
fos.pTo := PChar(_toDir);
end;
Result := (0 = ShFileOperation(fos));
_fromDir:= ExtractFilePath(_fromDir);
_toDir:= ExtractFilePath(_toDir);
end;
res := FindNext(SR);
end;
finally
FindClose(SR);
end;
end else
begin
_fromDir:= RemoveBackslashUnlessRoot(_fromDir) + #0#0;
_toDir := RemoveBackslashUnlessRoot(_toDir) + #0#0;
fos.pFrom := PChar(_fromDir);
fos.pTo := PChar(_toDir);
Result := (0 = ShFileOperation(fos));
end;
end;

function RenameDir(const fromDir, toDir: string): Boolean;
var
fos: TSHFileOpStruct;
_fromDir, _toDir: string;
begin
_fromDir:= RemoveBackslashUnlessRoot(fromDir) + #0#0;
_toDir := RemoveBackslashUnlessRoot(toDir) + #0#0;
fos.wFunc := FO_RENAME;
fos.fFlags := FOF_FILESONLY or FOF_ALLOWUNDO or
FOF_SILENT or FOF_NOCONFIRMATION;
fos.pFrom := PChar(_fromDir);
fos.pTo := PChar(_toDir);
Result := (0 = ShFileOperation(fos));
end;

procedure CreateBackup();
var
SrcFile, DestFile: string;
begin
if IsTaskSelected('arc') then
begin
BackupDir(ExpandConstant('{app}\123'), 'C:\123_old', False);
RenameDir(ExpandConstant('{app}'), ExpandConstant('{app}' + ' -' + GetDateTimeString('dd/mm/yyyy hh:nn:ss ', '-', '-') + '\'));
end;
end; [/more], в итоге ерунда получается((. В чем тут может быть трабл?..
Автор: serg_aka_lain
Дата сообщения: 11.07.2008 20:31
nOobCrafter

Цитата:
срабатывало по галочке (таску), в итоге ерунда получается((. В чем тут может быть трабл?..


А что не работает?
Папка "123" перемещается на C:\123_old, {app} переименовывается.?

з.ы "C:\123_old" лучше так будет - ExpandConstant('{sd}\123_old')
Автор: blaster4
Дата сообщения: 12.07.2008 01:20
Огромное спасибо !!! ExpeditorR

Разобрался в коде. Нужно было поменять:

SaveStringToFile(ExpandConstant('{app}')+'fl.ini', 'CDPATH: '+ExpandConstant('{app}'), True);
на
SaveStringToFile(ExpandConstant('{app}\fl.ini'), 'CDPATH: '+ExpandConstant('{app}'), True);

Второй раз написал отлично то, что нужно !!! Кстати с 0 не прокатило.

Хорошо, что есть такие люди, которые научившись сами не игнорируют тех кто еще с этим не сталкивался !!!

С Inno Setup работаю недавно, но если чем смогу помочь, всегда рад !!!
И еще извините, что редко пишу. Поздно прихожу с работы.

Еще раз огромное спасибо, и успехов с уважением blaster4 !!!

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970

Предыдущая тема: Презентация


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