PDA

Показать полную графическую версию : [архив] Скрипты Inno Setup. Помощь и советы [часть 2]


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 [61] 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

Sotonisto
04-02-2010, 19:37
так я же не говорил что мой! и автор не запрещал его выкладывать! »
YURSHAT говорит что я взял откуда-то этот скрипт и присвоил себе авторство, хотя я его впервые увидел тут когда вы его выложили.

P.S.: кстати а кто автор? просто мне бы хотелось узнать у него можно ли реализовать в инсталле пару моментов.

Tukash
04-02-2010, 19:40
Sotonisto
а для кого я его выложил? и YURSHAT не сказал Вам, что пользоватся нельзя, ему как и любому человеку не понравилось что его вещь присвоели себе!
PS: автор YURSHAT
Jerichoman
можно и по файлам, назови папку так-же, и кинь туда нужные тебе файлы, когда будут копироваться файлы, названия папок совпадут, и файлы попадут в нужную тебе папку, думаю понял!

Jerichoman
04-02-2010, 19:41
Tukash
Т.е. только по папкам паковать, по отдельности файлы никак не получится :( ?

YURSHAT
04-02-2010, 19:45
Sotonisto, я не прошу писать свое авторство и не запрещаю выкладывать просто когда выкладываете скрипт не нужно писать, что он от Sotonisto, ибо этим вы говорите, что вы автор...

Извиняюсь за оффтоп :off:

Tukash
04-02-2010, 19:57
YURSHAT
покажи именно где, если не трудно:
Поставь распаковку архивов на этап ssInstall, а ПО на ssPostInstall »

[Run]
Filename: {src}\DirectX\DXSETUP.exe; WorkingDir: {src}\DirectX; StatusMsg:
Filename: {src}\Redistributables\vcredist_x86.exe; WorkingDir: {src}\Redistributables; StatusMsg:


[Code]
const
Archives = '{src}\*.dat'; // укажите расположение архивов FreeArc; для внешних файлов строку в [Files] добавлять необязательно

PM_REMOVE = 1;
CP_ACP = 0; CP_UTF8 = 65001;
oneMb = 1048576;

type
#ifdef UNICODE ; если у вас ошибка на этой строке, то установите препроцессор или исправьте скрипт для вашей версии Inno Setup
#define A "W"
#else
#define A "A" ; точка входа в SetWindowText, {#A} меняется на A или W в зависимости от версии
PAnsiChar = PChar; // Required for Inno Setup 5.3.0 and higher. (требуется для Inno Setup версии 5.3.0 и ниже)
#endif
#if Ver < 84018176
AnsiString = String; // There is no need for this line in Inno Setup 5.2.4 and above (для Inno Setup версий 5.2.4 и выше эта строка не нужна)
#endif

TMyMsg = record
hwnd: HWND;
message: UINT;
wParam: Longint;
lParam: Longint;
time: DWORD;
pt: TPoint;
end;

TFreeArcCallback = function (what: PAnsiChar; int1, int2: Integer; str: PAnsiChar): Integer;
TArc = record Path: string; OrigSize: Integer; Size: Extended; end;

var
ExtractFile: TLabel;
lblExtractFileName: TLabel;
btnCancelUnpacking: TButton;
CancelCode, n, UnPackError, StartInstall: Integer;
Arcs: array of TArc;
msgError: string;
lastMb: Integer;
baseMb: Integer;
totalUncompressedSize: Integer; // total uncompressed size of archive data in mb
LastTimerEvent: DWORD;

Function MultiByteToWideChar(CodePage: UINT; dwFlags: DWORD; lpMultiByteStr: string; cbMultiByte: integer; lpWideCharStr: string; cchWideChar: integer): longint; external 'MultiByteToWideChar@kernel32.dll stdcall';
Function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD; lpWideCharStr: string; cchWideChar: integer; lpMultiByteStr: string; cbMultiByte: integer; lpDefaultChar: integer; lpUsedDefaultChar: integer): longint; external 'WideCharToMultiByte@kernel32.dll stdcall';

function PeekMessage(var lpMsg: TMyMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; external 'PeekMessageA@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMyMsg): BOOL; external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpMsg: TMyMsg): Longint; external 'DispatchMessageA@user32.dll stdcall';

Function OemToChar(lpszSrc, lpszDst: AnsiString): longint; external 'OemToCharA@user32.dll stdcall';
function GetWindowLong(hWnd, nIndex: Integer): Longint; external 'GetWindowLongA@user32 stdcall delayload';
function SetWindowText(hWnd: Longint; lpString: String): Longint; external 'SetWindowText{#A}@user32 stdcall delayload';

function GetTickCount: DWord; external 'GetTickCount@kernel32';
function WrapFreeArcCallback (callback: TFreeArcCallback; paramcount: integer):longword; external 'wrapcallback@files:innocallback.dll stdcall';
function FreeArcExtract (callback: longword; cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10: PAnsiChar): integer; external 'FreeArcExtract@files:unarc.dll cdecl';

procedure AppProcessMessage;
var
Msg: TMyMsg;
begin
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;

// Перевод числа в строку с точностью 3 знака (%.3n) с округлением дробной части, если она есть
Function NumToStr(Float: Extended): String;
Begin
Result:= Format('%.3n', [Float]); StringChange(Result, ',', '.');
while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Length(Result) > 1) do
SetLength(Result, Length(Result)-1);
End;

function cm(Message: String): String; Begin Result:= ExpandConstant('{cm:'+ Message +'}') End;

Function Size64(Hi, Lo: Integer): Extended;
Begin
Result:= Lo;
if Lo<0 then Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
for Hi:= Hi-1 Downto 0 do
Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
End;

// Converts OEM encoded string into ANSI
// Преобразует OEM строку в ANSI кодировку
function OemToAnsiStr( strSource: AnsiString): AnsiString;
var
nRet : longint;
begin
SetLength( Result, Length( strSource ) );
nRet:= OemToChar( strSource, Result );
end;

// Converts ANSI encoded string into UTF-8
// Преобразует строку из ANSI в UTF-8 кодировку
function AnsiToUtf8( strSource: string ): string;
var
nRet : integer;
WideCharBuf: string;
MultiByteBuf: string;
begin
strSource:= strSource + chr(0);
SetLength( WideCharBuf, Length( strSource ) * 2 );
SetLength( MultiByteBuf, Length( strSource ) * 2 );

nRet:= MultiByteToWideChar( CP_ACP, 0, strSource, -1, WideCharBuf, Length(WideCharBuf) );
nRet:= WideCharToMultiByte( CP_UTF8, 0, WideCharBuf, -1, MultiByteBuf, Length(MultiByteBuf), 0, 0);

Result:= MultiByteBuf;
end;

// OnClick event function for btnCancel
procedure btnCancelUnpackingOnClick(Sender: TObject);
begin
if MsgBox( SetupMessage( msgExitSetupMessage ), mbInformation, MB_YESNO ) = IDYES then
CancelCode:= -127;
end;

var origsize: Integer;
// The callback function for getting info about FreeArc archive
function FreeArcInfoCallback (what: PAnsiChar; Mb, sizeArc: Integer; str: PAnsiChar): Integer;
begin
if string(what)='origsize' then origsize := Mb else
if string(what)='compsize' then else
if string(what)='total_files' then else
Result:= CancelCode;
end;

// Returns decompressed size of files in archive
function ArchiveOrigSize(arcname: string): Integer;
var
callback: longword;
Begin
callback:= WrapFreeArcCallback(@FreeArcInfoCallback,4); //FreeArcInfoCallback has 4 arguments
CancelCode:= 0;
AppProcessMessage;
try
// Pass the specified arguments to 'unarc.dll'
Result:= FreeArcExtract (callback, 'l', '--', AnsiToUtf8(arcname), '', '', '', '', '', '', '');
if CancelCode < 0 then Result:= CancelCode;
if Result >= 0 then Result:= origsize;
except
Result:= -63; // ArcFail
end;
end;

// Scans the specified folders for archives and add them to list
function FindArcs(dir: string): Extended;
var
FSR: TFindRec;
Begin
Result:= 0;
if FindFirst(ExpandConstant(dir), FSR) then begin
try
repeat
// Skip everything but the folders
if FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY > 0 then CONTINUE;
n:= GetArrayLength(Arcs);
// Expand the folder list
SetArrayLength(Arcs, n +1);
Arcs[n].Path:= ExtractFilePath(ExpandConstant(dir)) + FSR.Name;
Arcs[n].Size:= Size64(FSR.SizeHigh, FSR.SizeLow);
Result:= Result + Arcs[n].Size;
Arcs[n].OrigSize := ArchiveOrigSize(Arcs[n].Path)
totalUncompressedSize := totalUncompressedSize + Arcs[n].OrigSize
until not FindNext(FSR);
finally
FindClose(FSR);
end;
end;
End;

// Sets the TaskBar title
Procedure SetTaskBarTitle(Title: String); var h: Integer;
Begin
h:= GetWindowLong(MainForm.Handle, -8); if h <> 0 then SetWindowText(h, Title);
End;

// Converts milliseconds to human-readable time
// Конвертирует милисекунды в человеко-читаемое изображение времени
Function TicksToTime(Ticks: DWord; h,m,s: String; detail: Boolean): String;
Begin
if detail {hh:mm:ss format} then
Result:= PADZ(IntToStr(Ticks/3600000), 2) +':'+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +':'+ PADZ(IntToStr(Ticks/1000 - Ticks/1000/60*60), 2)
else if Ticks/3600 >= 1000 {more than hour} then
Result:= IntToStr(Ticks/3600000) +h+' '+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +m
else if Ticks/60 >= 1000 {1..60 minutes} then
Result:= IntToStr(Ticks/60000) +m+' '+ PADZ(IntToStr(Ticks/1000 - Ticks/1000/60*60), 2) +s
else Result:= IntToStr(Ticks/1000) +s {less than one minute}
End;

// The main callback function for unpacking FreeArc archives
function FreeArcCallback (what: PAnsiChar; Mb, sizeArc: Integer; str: PAnsiChar): Integer;
var
percents, Remaining: Integer;
s: String;
begin
if GetTickCount - LastTimerEvent > 1000 then begin
// This code will be executed once each 1000 ms (этот код будет выполняться раз в 1000 миллисекунд)
// ....
// End of code executed by timer
LastTimerEvent := LastTimerEvent+1000;
end;

if string(what)='filename' then begin
// Update FileName label
lblExtractFileName.Caption:= FmtMessage( cm( 'Extracting' ), [OemToAnsiStr( str )] )
end else if (string(what)='write') and (totalUncompressedSize>0) and (Mb>lastMb) then begin
// Assign to Mb *total* amount of data extracted to the moment from all archives
lastMb := Mb;
Mb := baseMb+Mb;

// Update progress bar
WizardForm.ProgressGauge.Position:= Mb;

// Show how much megabytes/archives were processed up to the moment
percents:= (Mb*1000) div totalUncompressedSize;
s := FmtMessage(cm('ExtractedInfo'), [IntToStr(Mb), IntToStr(totalUncompressedSize)]);
if GetArrayLength(Arcs)>1 then
s := s + '. '+FmtMessage(cm('ArcInfo'), [IntToStr(n+1), IntToStr(GetArrayLength(Arcs))])
ExtractFile.Caption := s

// Calculate and show current percents
percents:= (Mb*1000) div totalUncompressedSize;
s:= FmtMessage(cm('AllProgress'), [Format('%.1n', [Abs(percents/10)])]);
if Mb > 0 then Remaining:= trunc((GetTickCount - StartInstall) * Abs((totalUncompressedSize - Mb)/Mb)) else Remaining:= 0;
if Remaining = 0 then SetTaskBarTitle(cm('ending')) else begin
s:= s + '. '+FmtMessage(cm('remains'), [TicksToTime(Remaining, cm('hour'), cm('min'), cm('sec'), false)])
SetTaskBarTitle(FmtMessage(cm('taskbar'), [IntToStr(percents/10), TicksToTime(Remaining, 'h', 'm', 's', false)]))
end;
WizardForm.FileNameLabel.Caption := s
end;
AppProcessMessage;
Result:= CancelCode;
end;

// Extracts all found archives
function UnPack(Archives: string): Integer;
var
totalCompressedSize: Extended;
callback: longword;
FreeMB, TotalMB: Cardinal;
begin
// Display 'Extracting FreeArc archive'
lblExtractFileName.Caption:= '';
lblExtractFileName.Show;
ExtractFile.caption:= cm('ArcTitle');
ExtractFile.Show;
// Show the 'Cancel unpacking' button and set it as default button
btnCancelUnpacking.Caption:= WizardForm.CancelButton.Caption;
btnCancelUnpacking.Show;
WizardForm.ActiveControl:= btnCancelUnpacking;
WizardForm.ProgressGauge.Position:= 0;
// Get the size of all archives
totalUncompressedSize := 0;
totalCompressedSize := FindArcs(Archives);
WizardForm.ProgressGauge.Max:= totalUncompressedSize;
// Other initializations
callback:= WrapFreeArcCallback(@FreeArcCallback,4); //FreeArcCallback has 4 arguments
StartInstall:= GetTickCount; {время начала распаковки}
LastTimerEvent:= GetTickCount;
baseMb:= 0

for n:= 0 to GetArrayLength(Arcs) -1 do
begin
lastMb := 0
CancelCode:= 0;
AppProcessMessage;
try
// Pass the specified arguments to 'unarc.dll'
Result:= FreeArcExtract (callback, 'x', '-o+', '-dp' + AnsiToUtf8( ExpandConstant('{app}') ), '--', AnsiToUtf8(Arcs[n].Path), '', '', '', '', '');
if CancelCode < 0 then Result:= CancelCode;
except
Result:= -63; // ArcFail
end;
baseMb:= baseMb+lastMb

// Error occured
if Result <> 0 then
begin
msgError:= FmtMessage(cm('ArcError'), [IntToStr(Result)]);
GetSpaceOnDisk(ExtractFileDrive(ExpandConstant('{app}')), True, FreeMB, TotalMB);
case Result of
-1: if FreeMB < 32 {Мб на диске} then msgError:= SetupMessage(msgDiskSpaceWarningTitle)
else msgError:= msgError + #13#10 + FmtMessage(cm('ArcBroken'), [ExtractFileName(Arcs[n].Path)]);
-127: msgError:= cm('ArcBreak'); //Cancel button
-63: msgError:= cm('ArcFail');
end;
// MsgBox(msgError, mbInformation, MB_OK); //сообщение показывается на странице завершения
Log(msgError);
Break; //прервать цикл распаковки
end;
end;
// Hide labels and button
WizardForm.FileNameLabel.Caption:= '';
lblExtractFileName.Hide;
ExtractFile.Hide;
btnCancelUnpacking.Hide;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
UnPackError:= UnPack(Archives)
if UnPackError = 0 then
SetTaskBarTitle(SetupMessage(msgSetupAppTitle))
else
begin
// Error occured, uninstall it then
Exec(ExpandConstant('{uninstallexe}'), '/SILENT','', sw_Hide, ewWaitUntilTerminated, n); //откат установки из-за ошибки unarc.dll
SetTaskBarTitle(SetupMessage(msgErrorTitle))
WizardForm.Caption:= SetupMessage(msgErrorTitle) +' - '+ cm('ArcBreak')
end;
end;
end;

// стандартный способ отката (не нужна CurPageChanged), но архивы распаковываются до извлечения файлов инсталлятора
// if CurStep = ssInstall then
// if UnPack(Archives) <> 0 then Abort;

Procedure CurPageChanged(CurPageID: Integer);
Begin
if (CurPageID = wpFinished) and (UnPackError <> 0) then
begin // Extraction was unsuccessful (распаковщик вернул ошибку)
// Show error message
WizardForm.FinishedLabel.Font.Color:= $0000C0; // red (красный)
WizardForm.FinishedLabel.Height:= WizardForm.FinishedLabel.Height * 2;
WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted) + #13#10#13#10 + msgError;
end;
End;

procedure InitializeWizard();
begin
with WizardForm.ProgressGauge do
begin
// Create a label to show current FileName being extracted
lblExtractFileName:= TLabel.Create(WizardForm);
lblExtractFileName.parent:=WizardForm.InstallingPage;
lblExtractFileName.autosize:=false;
lblExtractFileName.Width:= Width;
lblExtractFileName.top:=Top + ScaleY(35);
lblExtractFileName.Caption:= '';
lblExtractFileName.Hide;

// Create a label to show percentage
ExtractFile:= TLabel.Create(WizardForm);
ExtractFile.parent:=WizardForm.InstallingPage;
ExtractFile.autosize:=false;
ExtractFile.Width:= Width;
ExtractFile.top:=lblExtractFileName.Top + ScaleY(16);
ExtractFile.caption:= '';
ExtractFile.Hide;
end;

// Create a 'Cancel unpacking' button and hide it for now.
btnCancelUnpacking:=TButton.create(WizardForm);
btnCancelUnpacking.Parent:= WizardForm;
btnCancelUnpacking.SetBounds(WizardForm.CancelButton.Left, WizardForm.CancelButton.top, WizardForm.CancelButton.Width, WizardForm.CancelButton.Height);
btnCancelUnpacking.OnClick:= @btnCancelUnpackingOnClick;
btnCancelUnpacking.Hide;
end;

Sotonisto
04-02-2010, 20:01
YURSHAT, ну тогда извиняюсь если я что-то не так сделал. Ну могли бы вы тогда на мое сообщение ответить (когда я просил скрипт инсталла).

Я написал что скрипт на ргосте от меня так как там были все файлы которые я сам достал и использовал и отредактированый мною скрипт.
Тем более все ж видели что скрипт изначально был от нфс, я и не думал что кто-то будет говорить что я автор оригинала.
Я еле 3 psd исходника достал и картинки флагов :( пришлось самому искать dll'ки и настраивать "под себя" установку озвучки.

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

Tukash, написали бы сначала что автор - YURSHAT я б ему все свои проблемы с инсталлом в личку писал а не на форум :(

user_123
04-02-2010, 20:02
Прочитал в руководствах по Inno Setup о двух различных методах защиты инсталлятора от "вскрытия".

1. Автоматически заполняется поле ввода пароля.
2. Поле ввода пароля не заполняется вообще, а в функции проверки пароля пишем:Result:= True

Первый метод я освоил и уже применял на практике... Но второй меня удивил... В руководстве, в котором я о нём прочёл, он назван "Невзламываемый экзешник".

Понятно, что раз поле ввода пароля не заполняется, значит и "вынуть" этот самый пароль не от куда...
Хочу узнать у опытных программистов, какой из этих двух методов надёжнее... а так же, что именно так хорошо защищает второй метод: запакованный контент или исходник, или и то и другое?

serega355
04-02-2010, 20:03
Пользователи, обратите внимание плиз на мой вопрос.

Tukash
04-02-2010, 20:06
Tukash, написалибы чтоавтор YURSHAT я б ему все свои проблемы с инсталлом в личку писал а не на форум »
да я больше не буду так, хотел как лучше, а получилось...

YURSHAT
04-02-2010, 20:20
Я написал что скрипт на ргосте от меня так как там были все файлы которые я сам достал и использовал и отредактированый мною скрипт. »

Посмотрев скрипт, я не увидел там что-то нового.

Тем более все ж видели что скрипт изначально был от нфс, я и не думал что кто-то будет говорить что я автор оригинала. »

А никто и не говорил. Просто я случайно глянул и увидел скрипт. Скачал, посмотрел - мой скрипт, а написано от Sotonisto.

Я еле 3 psd исходника достал и картинки флагов пришлось самому искать dll'ки и настраивать "под себя" установку озвучки. »

PSD исходники и флаги думаю тоже мои (на скрине точно мои).

Вы же видели сообщения где я просил что бы мне помогли с реализацией, а не ответили что так трудно было ответить? »

Если не ответил, значит на то были свои причины (не было времени или просто сообщение не увидил).

Думаю этот вопрос нужно закрыть!!! ОффТопа и так хватает...

user_123
04-02-2010, 20:29
Прочитал в руководствах по Inno Setup о двух различных методах защиты инсталлятора от "вскрытия".

1. Автоматически заполняется поле ввода пароля.
2. Поле ввода пароля не заполняется вообще, а в функции проверки пароля пишем:Result:= True

Первый метод я освоил и уже применял на практике... Но второй меня удивил... В руководстве, в котором я о нём прочёл, он назван "Невзламываемый экзешник".

Понятно, что раз поле ввода пароля не заполняется, значит и "вынуть" этот самый пароль не от куда...
Хочу узнать у опытных программистов, какой из этих двух методов надёжнее... а так же, что именно так хорошо защищает второй метод: запакованный контент или исходник, или и то и другое?

И ещё 1 вопрос, связанный с защитой инсталлятора...
Если зашифровать инсталлятор ([setup] Encryption=Yes), то возникают проблемы при использовании дополнительных dll ([Files] Flags: dontcopy).
Насколько хорошо защищён инсталлятор (в т.ч. его исходник) если использовать пароль без шифрования?

Подскажите, как использовать доп. библиотеки вместе с шифрованием, как их извлекать после подтверждения пароля (но до распаковки основных файлов)...

semiono
04-02-2010, 20:54
Столкнулся с такой трудностью:
DefaultDirName={reg:HKLM32\Software\test,ID|{cf}\{{9EA325EA-2012-4EFD-83AA-1EF32414E39F}}
Данный код создаёт папку: {9EA325EA-2012-4EFD-83AA-1EF32414E39F}} в {cf}\

Вообщем выход нашёл такой:
DefaultDirName={reg:HKLM32\Software\VST,PID|{cf}\{code:CLSID}}

[код]
function CLSID(Param: String): String;
begin
Result := ExpandConstant('{{9EA325EA-2012-4EFD-83AA-1EF32414E39F}');
end;
Так я решил проблему с квотированием. :)

semiono
04-02-2010, 22:44
Опять загвоздка новая! Нужно в реестре перевернуть слеш...

"InstallDir" = D:\la-la-la
заменить на
"InstallDir" = D:/la-la-la/

Как это можно зделать? Слеш в конце обязателен!
Длина пути и вложенность директорий разумеется неопределены и могут быть разными.

----
Ну ежели в InnoSetup нету api ? Тогда я написал пару строк Aut2Exe zzz.au3 для [Run]

RegWrite("HKCU\Software\Nexus", "ContentPath", "REG_SZ", StringRegExpReplace( RegRead("HKCU\Software\Nexus", "ContentPath"), "\\", "/") & "/")

Но InnoSetup хотелось бы всё же тоже узнать. ??

serg aka lain
05-02-2010, 00:06
Но InnoSetup хотелось бы всё же тоже узнать. ?? »
Можно так

procedure CurStepChanged(CurStep: TSetupStep);
var
S: String;
begin
if CurStep = ssPostInstall then
begin
S := AddBackSlash(ExpandConstant('{app}'));
StringChangeEx(S, '\', '/', True);
RegWriteStringValue(HKLM, 'Software\My Company\My Program', 'InstallDir', S);
end;
end;

svensoft
05-02-2010, 01:58
YURSHAT, скажи пожалуйста какой параметр нужно указать при загрузке скина, чтобы рамка скина была снаружи ?.. У меня при загрузке скина рамка вставляется внутрь WizardForm , тем самым сдвигая фон вместе со всем находящимся на нем и мне приходится размеры WizardForm подгонять вручную, т.е. фоновый рисунок предположим 790*533 , при этом размеры WizardForm приходится вручную корректировать - ровно на рамку больше 793*563 .. :unsure:

МИШАНЧИК
05-02-2010, 04:17
Sotonisto, спасибо.
Подскажите пожалуйста, я сделал на финишной странице чекбокс, а как сделать чтоб он открывал ReadMe.txt находящийся в {app}? »
Код:
[Run]
Filename: {app}\ReadMe.txt; Flags: shellexec postinstall skipifsilent »
Ты примерно так хотел? »
Только я хотел не из [Run], а из секции [_Code]
Помогите пожалуйста, кто знает как это сделать.

Serega
05-02-2010, 10:19
Может, кто- нибудь знает какой код надо ввести, чтобы на любой диск при её установке каталог был Rockstar Games\GTA »

[Setup]
AppName=Rockstar Games
AppVerName=Rockstar Games v 1.5
DefaultDirName={pf}\Rockstar Games\GTA
OutputDir=.
Compression=lzma/ultra
InternalCompressLevel=ultra
SolidCompression=yes

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

[Code]
function LastPos(symbol, str: string): Integer;
var
i: Integer;
begin
for i:= Length(str) downto 1 do
if str[i] = symbol then Break;
Result:= i;
end;

procedure DirEditChange(Sender: TObject);
var
n: Integer;
s: string;
begin
n:= LastPos('\', WizardForm.DirEdit.Text);
s:= Copy(WizardForm.DirEdit.Text, 1, n);
if Pos('Rockstar Games\GTA', WizardForm.DirEdit.Text) = 0 then
WizardForm.DirEdit.Text:= s + 'Rockstar Games\GTA';
end;

procedure InitializeWizard();
begin
WizardForm.DirEdit.OnChange:= @DirEditChange;
end;


Создаю инсталлятор, и когда устанавливаю игру в реестр заносится только один путь из двух. »
почитайте внимательно Справку

deletekey
Когда установлен этот флаг, инсталлятор сначала попытается удалить ключ, если он существует, со всеми его параметрами и разделами. Если ValueType=none, после этого он создаст новый ключ и параметр.
Для предотвращения негативных последствий, этот флаг игнорируется при установке, если Subkey пустой или состоит только из бэкслешей.

т.е. у вас при внесении второго ключа, сначала удаляется первый.

Нужно в реестре перевернуть слеш... »
Почитайте справку, вам поможет function StringChange(var S: String; const FromStr, ToStr: String): Integer;

я сделал на финишной странице чекбокс, а как сделать чтоб он открывал ReadMe.txt находящийся в {app}? »
Каким образом сделали?
Если через [Соdе], то задаёте ему событие OnClick с ссылкой на процедуру, в которой проверяете, если чебокс отмечен, то запускаете свой файл через function ShellExec(const Verb, Filename, Params, WorkingDir: String; const ShowCmd: Integer; const Wait: TExecWait; var ErrorCode: Integer): Boolean;

МИШАНЧИК
05-02-2010, 11:44
Serega, спасибо!
Каким образом сделали?
Если через [Соdе], то задаёте ему событие OnClick с ссылкой на процедуру »
А можно примером, короткий скрипт, для наглядности?
Заранее большое спасибо!
P.S. А если создать чекбокс на вкладке WizardForm Designer, на этой же вкладке можно к ниму как-то прицепить действие?

Serega
05-02-2010, 13:58
А если создать чекбокс на вкладке WizardForm Designer, на этой же вкладке можно к ниму как-то прицепить действие? »
Нет, нужно писать в ручную.
Сделал обычную проверку на отмеченный чебокс при завершении инсталляции. Чебокс сделал в WizardForm Designer.

[Setup]
AppName=My Program
AppVerName=My Program v 1.5
DefaultDirName={pf}\My Program
OutputDir=.
Compression=lzma/ultra
InternalCompressLevel=ultra
SolidCompression=yes

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

[Files]
Source: compiler:Examples\Readme.txt; DestDir: {app}; Flags: ignoreversion

[Code]
{ RedesignWizardFormBegin } // Don't remove this line!
// Don't modify this section. It is generated automatically.
var
NewCheckBox1: TNewCheckBox;

procedure RedesignWizardForm;
begin
{ NewCheckBox1 }
NewCheckBox1 := TNewCheckBox.Create(WizardForm);
with NewCheckBox1 do
begin
Parent := WizardForm.FinishedPage;
Left := ScaleX(216);
Top := ScaleY(192);
Width := ScaleX(137);
Height := ScaleY(17);
Caption := 'Прочитать Readme.txt';
Checked := True;
State := cbChecked;
end;

NewCheckBox1.TabOrder := 5;

{ ReservationBegin }
// This part is for you. Add your specialized code here.

{ ReservationEnd }
end;
// Don't modify this section. It is generated automatically.
{ RedesignWizardFormEnd } // Don't remove this line!

procedure InitializeWizard();
begin
RedesignWizardForm;
end;

procedure DeinitializeSetup();
var
ResultCode: Integer;
begin
if NewCheckBox1.Checked then
ShellExec('open', 'Readme.txt', '', ExpandConstant('{app}'), SW_SHOWNORMAL, ewNoWait, ResultCode);
end;

[ISFormDesigner]
WizardForm=FF0A005457495A415244464F524D003010CB01000054504630F10B5457697A617264466F726D0A57697A61726 4466F726D0C436C69656E744865696768740366010B436C69656E74576964746803EF010C4578706C696369744C656674020 00B4578706C69636974546F7002000D4578706C69636974576964746803F7010E4578706C696369744865696768740383010 D506978656C73506572496E636802600A54657874486569676874020D00F10C544E65774E6F7465626F6F6B0D4F757465724 E6F7465626F6F6B00F110544E65774E6F7465626F6F6B506167650B57656C636F6D65506167650D4578706C6963697457696 4746803F1010E4578706C696369744865696768740339010000F110544E65774E6F7465626F6F6B506167650C46696E69736 86564506167650D4578706C69636974576964746803F1010E4578706C69636974486569676874033901000C544E657743686 5636B426F780C4E6577436865636B426F7831044C65667403D80003546F7003C000055769647468038900064865696768740 2110743617074696F6E141D000000D09FD180D0BED187D0B8D182D0B0D182D18C20526561646D652E74787407436865636B6 5640905537461746507096362436865636B6564085461624F7264657202050000000000

МИШАНЧИК
05-02-2010, 15:48
Serega, спасибо!
И ещё вопрос. В инсталшилде при установке дополнительного п.о. на фоне инсталятора появляется маленькая картинка на которой написано "Устанавливается DirectX". У меня DirectX устанавливается так:
procedure CurStepChanged(CurStep: TSetupStep);
Var
ResultCode: integer;
begin
if CurStep = ssPostInstall then
begin
if DirectX.Checked then
begin
StatusLabel.Caption:=ExpandConstant('{cm:DirectXInstall}')
Exec(ExpandConstant('{src}\Redist\DirectX\DXSETUP.exe'), '/silent', ExpandConstant('{src}\Redist\DirectX'), SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
end;
end;
А можно ли как-то сделать чтоб на этом фоне тоже появлялась маленькая картинка?




© OSzone.net 2001-2012