PDA

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


Страниц : 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

TROY Diamond
27-01-2019, 00:27
требуемый размер недоступен извне, повлиять на величину можно только в большую сторону.

1. El Sanchez А, как же например, в репаках игр указывают Для установки (распаковки) требуется столько-то места и если его меньше установку продолжить невозможно? Это значение ведь указывается вручную?

2. El Sanchez и Iska - НЕ знаю у кого спросить, подскажите, пожалуйста, где можно найти информацию про подписывания цифровой подписью своего дистрибутива? Видел такую реализацию в некоторых репаках сделанных в Inno Setip и аддонах на основе SFX-архивов и Inno Setup. Пусть это будет "НЕ серьезная" цифровая подпись - просто чтобы проверяла целостность и контрольные суммы файла.

Iska
27-01-2019, 01:09
Это значение ведь указывается вручную? »
Нет. Эти значения рассчитываются автоматически при создании инсталлятора в зависимости от объёма результирующих файлов.

TROY Diamond
27-01-2019, 02:10
Iska, нет это нечто иное сделанное с помощью скрипта, т.к. дальнейшая установка невозможна если места не хватает! А "значения рассчитываются автоматически" - только информирует.

P.S. По второму вопросу кто может помочь?

Iska
27-01-2019, 05:48
дальнейшая установка невозможна если места не хватает! »
Естественно. Откуда может взяться возможность что-то записать на раздел, если на нём не осталось свободного места?!

El Sanchez
27-01-2019, 11:03
Но можно проверить его уникальность по существующим уже в базам. Это уже хоть что-то. »
Нет у вас баз.
если сюда включить OS и возможно какие то другие уникальные данные (например дату установки винды, или какие то данные из реестра) то уже можно хоть какой то портрет пользователя получить. »
1specific, OS, MAC, IP, CPUID, BIOS - все не то. Более-менее подходит связка серийный номер MB + код производителя HDD, на котором система лежит. Только серверу от этого HWID ни горячо, ни холодно.
Придумать какую-нибудь простенькую контрольную сумму, которую включать в отсылаемые данные, и по которой сервер сможет судить о том, что переданные данные были сгенерированы программно, а не представляют собой случайную отсебятину для накруток. »
Iska, алгоритм должен быть известен и серверу и установщику, а скриптовый движок в Inno штука ненадежная - можно восстановить исходный код секции Code до такого вида, что будет давать идентичный байткод.

1specific
27-01-2019, 11:17
Нет у вас баз. »
В смысле нету? Речь о моей базе. HWID туда записывается. Если такой уже есть в базе значит не засчитывается утсановка.

В целом не понятно какие варианты тогда есть чтобы реализовать задумку на уровне inno setup?)

nik1967
27-01-2019, 14:24
где можно найти информацию про подписывания цифровой подписью своего дистрибутива?»
Ответил в PM.


#Define NeedSize 5000
;;Если у вас архивы FreeArc, то здесь укажите сколько необходимо места в Мб
;;Иначе просто закоментируйте строку
;;Автор: Shegorat

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

[Languages]
Name: ENG; MessagesFile: "compiler:Default.isl"
Name: RUS; MessagesFile: "compiler:Languages\Russian.isl"

[Files]
Source: {win}\help\*.hlp; DestDir: {app}\Files; Flags: external

[CustomMessages]
RUS.FreeSpace=Доступно места на диске:
RUS.NeedSpace=Требуется места на диске:
RUS.MB=Мб
RUS.GB=Гб
RUS.TB=Тб
ENG.FreeSpace=Free space on disk:
ENG.NeedSpace=Need space on disk:
ENG.MB=Mb
ENG.GB=Gb
ENG.TB=Tb

[Code]
var
NeedSpaceLabel,FreeSpaceLabel: TLabel;
FreeMB, TotalMB: Cardinal;
SizeStr: String;
SizeInt: Integer;
SymbolNumber: Integer;

function GetSize(): Integer;
begin
SizeStr:= WizardForm.DiskSpaceLabel.Caption;
for SymbolNumber:= 97 to 122 do begin
while (Pos(Chr(SymbolNumber), SizeStr) > 0) do Delete(SizeStr, Pos(Chr(SymbolNumber), SizeStr),1);
while (Pos(AnsiUppercase(Chr(SymbolNumber)), SizeStr) > 0) do Delete(SizeStr, Pos(AnsiUppercase(Chr(SymbolNumber)), SizeStr),1);
end;
for SymbolNumber:= 192 to 255 do begin
while (Pos(Chr(SymbolNumber), SizeStr) > 0) do Delete(SizeStr, Pos(Chr(SymbolNumber), SizeStr),1);
end;
while (Pos('.', SizeStr) > 0) do Delete(SizeStr, Pos('.', SizeStr), 1);
Delete(SizeStr, Pos(',', SizeStr), 5)
Result:= StrToInt(Trim(SizeStr));
end;

function CompareNum(FirstNum, SecondNum: Integer): Boolean;
begin
if FirstNum < SecondNum then Result:= False else Result:= True;
end;

function NumToStr(Float: Extended): String;
begin
Result:= Format('%.2f', [Float]);
StringChange(Result, ',', '.');
while ( Pos('.', Result) > 0 ) and ( (Result[Length(Result)] = '0') or (Result[Length(Result)] = '.') ) do
SetLength(Result, Length(Result) - 1);
end;

function MbOrTb(Float: Extended): String;
begin
if Float < 1024 then Result:= NumToStr(Float)+ExpandConstant(' {cm:MB}') else
if Float/1024 < 1024 then Result:= NumToStr(Float/1024)+ExpandConstant(' {cm:GB}') else
Result:= NumToStr(Float/(1024*1024))+ExpandConstant(' {cm:TB}');
end;

procedure GetFreeSpaceCaption(Sender: TObject);
var
Path: String;
begin
Path:= ExtractFileDrive(WizardForm.DirEdit.Text);
GetSpaceOnDisk(Path, True, FreeMB, TotalMB);
FreeSpaceLabel.Caption:= ExpandConstant('{cm:FreeSpace} ') + MbOrTb(FreeMB);
NeedSpaceLabel.Caption:= ExpandConstant('{cm:NeedSpace} ') + MbOrTb(SizeInt);
if WizardForm.CurPageID = wpSelectDir then begin
WizardForm.NextButton.Enabled:= CompareNum(FreeMB, SizeInt);
end;
end;

procedure InitializeWizard();
begin
WizardForm.DiskSpaceLabel.Hide;
#ifdef NeedSize
SizeInt:= {#NeedSize}
#else
SizeInt:= GetSize;
#endif

NeedSpaceLabel:= TLabel.Create(WizardForm);
NeedSpaceLabel.SetBounds(ScaleX(0), ScaleY(198), ScaleX(209), ScaleY(13))
NeedSpaceLabel.Parent:= WizardForm.SelectDirPage;
NeedSpaceLabel.Transparent:= true;

FreeSpaceLabel:= TLabel.Create(WizardForm);
FreeSpaceLabel.SetBounds(ScaleX(0), ScaleY(216), ScaleX(209), ScaleY(13))
FreeSpaceLabel.Parent:= WizardForm.SelectDirPage;
FreeSpaceLabel.Transparent:= true;

WizardForm.DirEdit.OnChange:= @GetFreeSpaceCaption;
WizardForm.DirEdit.Text:= WizardForm.DirEdit.Text + #0;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpSelectDir then GetFreeSpaceCaption(nil);
end;

Iska
27-01-2019, 14:50
Iska, алгоритм должен быть известен и серверу и установщику »
Конечно. Иначе — какой смысл?!

а скриптовый движок в Inno штука ненадежная - можно восстановить исходный код секции Code до такого вида, что будет давать идентичный байткод. »
Ото ж. Третий довод в пользу того, что:
…«стучать» надо из самого приложения, а не из инсталляции. »
:).

1specific
27-01-2019, 18:49
Ото ж. Третий довод в пользу того, что:
Цитата Iska:
…«стучать» надо из самого приложения, а не из инсталляции. » »

Возможности такой нет.
Значит делаем как можем.
Кто готов - пожалуйста, буду рад обсудить детали и приступить.
На данный момент нужно хоть какое то решение, дальше уже можно будет переделывать и улучшать.

TROY Diamond
27-01-2019, 19:36
Естественно. Откуда может взяться возможность что-то записать на раздел, если на нём не осталось свободного места?!

Iska, почему-то nik1967 - понял о чём речь и как сделать?

Iska
27-01-2019, 20:23
TROY Diamond, значит, я был не прав. Однако сие никак не поможет изменить ситуацию, если места действительно не хватает.

El Sanchez
27-01-2019, 20:41
Значит делаем как можем. »
1specific, можно ограничиться серверной частью примерно так:
1. Компилируется мастер-копия установщика.
2. Клиент по партнерской ссылке запрашивает файл.
3. Сервер делает копию мастер-файла, генерирует GUID и записывает его в конец копии.
4. Копия отдается клиенту.
5. Если ошибок при приеме-передаче не было, GUID заносится в таблицу партнера в БД.
6. Сервер удаляет копию.
7. Установщик в конце установки считывает GUID и посылает его на сервер GET-запросом в параметрах.
8. Сервер проверяет GUID в БД. Если есть, то гут, партнеру +1, GUID удаляется из БД. Если нет, то попытка накрутки, баловство и прочие ништяки, с которыми скоро придется познакомиться.
почему-то nik1967 - понял о чём речь и как сделать »
TROY Diamond, а толку? Установщик посчитает 15 ГБ, а вы отобразите 10 ГБ. Если у юзера будет свободного места от 10 до 15 ГБ, то он увидит ругань, что нет места, а в ваш адрес полетит ругань уже юзерскыя, мол, "у миня 14 гигов ессть еще, какого оно 10 пишит тада?" (орфография пользователя сохранена)

1specific
27-01-2019, 23:17
Компилируется мастер-копия установщика. »
Каким образом сделать это на php? Я не встречал такого компилятора inno setup для php (а веб часть будет на php)

Сервер делает копию мастер-файла, генерирует GUID и записывает его в конец копии. »
Какие в этом преимущества? md5 всё-ровно поменяется для каждой копии.


По сути вся схема реализации уже понятна.
От инсталлятора просто требуется отправить нужные данные на сервер и всё (+ возможно добавление контрольной суммы к каким то данным) . Это небольшой кусок кода. Возьметесь?

TROY Diamond
27-01-2019, 23:51
а толку? Установщик посчитает 15 ГБ, а вы отобразите 10 ГБ. Если у юзера будет свободного места от 10 до 15 ГБ, то он увидит ругань, что нет места, а в ваш адрес полетит ругань уже юзерскыя, мол, "у миня 14 гигов ессть еще, какого оно 10 пишит тада?" (орфография пользователя сохранена)

El Sanchez, поэтому я вас ОЧЕНЬ и просил такой скрипт, который будет удалять сразу все временные папки в процессе установки по её ходу, а НЕ по её окончании, как это делается в большинстве репаков игр!

Например, один архив (УСЛОВНО) весит в упакованном виде 700 МБ, распакованная папка, которая будет скопирована в процессе установки, будет занимать на ЖД 1,5 ГБ (условно), через 1-2 минуты ЭТА ПАПКА, будет упакована в архив и СРАЖУ ЖЕ УДАЛЕНА, останется только 700 МБ архив на ЖД пользователя, начнётся копирование следующей папки, которая также упакуется в архив и удалится. Поэтому 15 ГБ, с запасом хватит, а если бы папки НЕ удалялись бы сразу же, то тогда нужно было бы как раз 30 ГБ места на ЖД.

Игра в конечном итоге (в готовом к "употреблению" виде), по окончании установки, занимает на ЖД - всего 12 ГБ (условно) - я хочу задать 15 ГБ, с запасом, вместо 20-25 ГБ, сколько хочет Inno Setip из расчёта скомпилированного...

El Sanchez, мы друг друга правильно поняли? Теперь когда всё ясно можете, помочь?

El Sanchez
28-01-2019, 13:12
Каким образом сделать это на php? Я не встречал такого компилятора inno setup для php (а веб часть будет на php) »
1specific, мастер-копия - это то, что вы в Inno Setup сделаете и на свой сервер закинете. Измененные копии этого файла идут клиентам.
Какие в этом преимущества? md5 всё-ровно поменяется для каждой копии. »
1specific, клиенту перед отправкой подтверждения установки необходимо будет эту MD5 посчитать, а это небыстрая операция, если файл большой.
От инсталлятора просто требуется отправить нужные данные на сервер и всё (+ возможно добавление контрольной суммы к каким то данным) . Это небольшой кусок кода. »
1specific, отправляйте:

[Code]
#define A = (Defined UNICODE) ? "W" : "A"
const
SXH_PROXY_SET_PROXY = 2;

procedure SendID;
var
XMLHTTP: Variant;
ProxyEnable: Cardinal;
ProxyServer, ProxyOverride: string;
Data: AnsiString;
begin
XMLHTTP := CreateOleObject('MSXML2.ServerXMLHTTP');
try
if RegQueryDWordValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Internet Settings', 'ProxyEnable', ProxyEnable) and (ProxyEnable = 1) then
begin
if RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Internet Settings', 'ProxyServer', ProxyServer) and
RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Internet Settings', 'ProxyOverride', ProxyOverride) then
XMLHTTP.setProxy(SXH_PROXY_SET_PROXY, ProxyServer, ProxyOverride);
end;
XMLHTTP.open('POST', 'https://httpbin.org/post'{'http://site.ru/success.php'}, False);
XMLHTTP.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
Data := 'id=12345678'; // custom data
XMLHTTP.send(Data);
Log(Format('Error Code: %s %s', [XMLHTTP.status, XMLHTTP.statusText]));
except
Log(GetExceptionMessage);
finally
end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
case CurStep of
ssPostInstall: SendID;
end;
end;


один архив (УСЛОВНО) весит в упакованном виде 700 МБ, распакованная папка, которая будет скопирована в процессе установки, будет занимать на ЖД 1,5 ГБ (условно), через 1-2 минуты ЭТА ПАПКА, будет упакована в архив и СРАЖУ ЖЕ УДАЛЕНА, останется только 700 МБ архив на ЖД пользователя, начнётся копирование следующей папки, которая также упакуется в архив и удалится. Поэтому 15 ГБ, с запасом хватит, а если бы папки НЕ удалялись бы сразу же, то тогда нужно было бы как раз 30 ГБ места на ЖД. »
TROY Diamond, я это и сделал.
Игра в конечном итоге (в готовом к "употреблению" виде), по окончании установки, занимает на ЖД - всего 12 ГБ (условно) - я хочу задать 15 ГБ, с запасом, вместо 20-25 ГБ, сколько хочет Inno Setip из расчёта скомпилированного »
TROY Diamond, уменьшить требуемый размер 20-25 ГБ вы не сможете, величина рассчитывается в run-time и зависит от выбранных компонентов (если есть). Можно только увеличить через директиву ExtraDiskSpaceRequired. На знак "минус" в ее значении Inno ругается, отрицательное число в 16-тиричном представлении тоже не фурычит.

TROY Diamond
28-01-2019, 21:12
El Sanchez и что никак не решаемо?

GrezeeBal
01-02-2019, 19:32
Привет! Сразу скажу, что очень плохо разбираюсь в коде.

В общем, делаю установщик модификации для игры GTA и при установке данной игры в реестре создаётся путь к файлу gta_sa.exe(исполняемый файл). Я указываю в установщик путь к данному значению в реестр, чтобы в установщике автоматически указалась папка с игрой в качестве пути, но так как значение в реестре ведет прямо к exe файлу - он указывается в пути по умолчанию.

Вопрос: как исключить этот файл из значения, чтобы указывалась только папка с игрой?

https://i.imgur.com/EJtdNSt.png

https://i.imgur.com/W7N3hk7.png

DefaultDirName={reg:HKCU\Software\SAMP,gta_sa_exe|}

El Sanchez
01-02-2019, 21:39
Вопрос: как исключить этот файл из значения, чтобы указывалась только папка с игрой? »
GrezeeBal,
DefaultDirName={code:ExtractFileDir|{reg:HKCU\Software\SAMP,gta_sa_exe|}}

GrezeeBal
01-02-2019, 22:04
DefaultDirName={code:ExtractFileDir|{reg:HKCU\Software\SAMP,gta_sa_exe|}} »
Спасибо большое!

OldGamer
12-02-2019, 15:15
Здравствуйте!

Помогите, пожалуйста, разобраться с функцией AnimateWindow+прозрачностью окна при перемещении.

Проблема в следующем:

1) Плавное закрытие инсталлятора при выходе - работает (или работало) на отлично!

2) Добавил прозрачность окна при перемещении - работает, но плавное закрытие окна инсталлятора при нажатии на кнопку "Отмена" работать перестаёт.

Заранее Большое Спасибо!!!



const
WM_NCLBUTTONDOWN = $00A1;
HTCAPTION = 2;
WM_NCMOUSEMOVE = $00A0;
GWL_EXSTYLE = -20;
WS_EX_LAYERED = $80000;
LWA_ALPHA = 2;
TransparentPercent = 50;

var
ComponentPage : TWizardPage;
InstallGroupBox : TNewGroupBox;
Installer : TNewRadioButton;
Portable : TNewRadioButton;

function InstallerCheck: Boolean;
begin
Result := Installer.Checked;
end;

function PortableCheck: Boolean;
begin
Result := Portable.Checked;
end;

type TGUID = record Data1: Cardinal; Data2, Data3: Word; Data4: array [0..8] of Char; end;

const PlayTask = 0;
SupportTask = 1;
var GameuxGUID: TGUID;

function GenerateGUID(var GUID: TGUID): Cardinal; external 'GenerateGUID@files:GameuxInstallHelper.dll stdcall setuponly';
function AddToGameExplorer(Binary: String; Path: String; InstallType: Integer; var GUID: TGUID): Cardinal; external 'AddToGameExplorerA@files:GameuxInstallHelper.dll stdcall setuponly';
function CreateTask(InstallType: Integer; var GUID: TGUID; TaskType: Integer; TaskNumber: Integer; TaskName: String; Binary: String; Parameters: String): Cardinal; external 'CreateTaskA@files:GameuxInstallHelper.dll stdcall setuponly';
function RetrieveGUIDForApplication(Binary: String; var GUID: TGUID): Cardinal; external 'RetrieveGUIDForApplicationA@{localappdata}\GameuxInstallHelper.dll stdcall uninstallonly';
function RemoveFromGameExplorer(var GUID: TGUID): Cardinal; external 'RemoveFromGameExplorer@{localappdata}\GameuxInstallHelper.dll stdcall uninstallonly';
function RemoveTasks(var GUID: TGUID): Cardinal; external 'RemoveTasks@{localappdata}\GameuxInstallHelper.dll stdcall uninstallonly';
procedure LoadSkin(lpszPath: String; lpszIniFileName: String); external 'LoadSkin@files:isskin.dll stdcall';
procedure UnloadSkin(); external 'UnloadSkin@files:isskin.dll stdcall';

function IntToHex(Int: Cardinal; Digits: Integer): String; var i, Digit: Integer; ch: Byte;
begin
result:='';
for i:=0 to Digits-1 do
begin
digit:=Int mod 16;
Int:=Int div 16;
if digit<0 then
digit:=digit+16;
ch:=Ord('0')+digit;
if digit>9 then
ch:=ch+7;
result:=chr(ch)+result;
end;
end;

function GetGUID(GGUID: TGUID): String; var i: Integer;
begin
result:='{'+IntToHex(GGUID.Data1, 8)+'-'+IntToHex(GGUID.Data2, 4)+'-'+IntToHex(GGUID.Data3, 4)+'-'+IntToHex(Ord(GGUID.Data4[0]), 2)+IntToHex(Ord(GGUID.Data4[1]), 2)+'-';
for i:=2 to 7 do result:=result+IntToHex(Ord(GGUID.Data4[i]), 2); result:=result+'}';
end;

procedure GDFInstall(Binary, MainExe: String);
begin
GenerateGUID(GameuxGUID);
AddToGameExplorer(ExpandConstant(Binary), ExpandConstant('{app}'), 3, GameuxGUID);

CreateTask(3, GameuxGUID, PlayTask, 0, 'Play', ExpandConstant(MainExe), '');
end;

procedure win7fix;
var regGDF: Cardinal;
var GUXPath: string;
begin
GUXPath := 'Software\Microsoft\Windows\CurrentVersion\GameUX\Games\' + GetGUID(GameuxGUID);
if isWin64 then
begin
if RegQueryDWordValue(HKLM64, GUXPath, 'IsSigned', regGDF) then
if regGDF=0 then
if RegDeleteValue(HKLM64, GUXPath, 'IsSigned') then
RegWriteDWordValue(HKLM64, GUXPath, 'IsSigned', 1);
end
else
begin
if RegQueryDWordValue(HKLM, GUXPath, 'IsSigned', regGDF) then
if regGDF=0 then
if RegDeleteValue(HKLM, GUXPath, 'IsSigned') then
RegWriteDWordValue(HKLM, GUXPath, 'IsSigned', 1);
end;
end;

type
TPBProc = function (h:hWnd;Msg,wParam,lParam:Longint):Longint;

var
TimeLeftLabel : TLabel;

PBOldProc : Longint;
eTime, sTime : DWORD;

var
BASS_Initialized: Boolean;

const
AW_BLEND = $00080000;
AW_HIDE = $00010000;
const
LOAD_LIBRARY_AS_DATAFILE = $2;

#define A = (Defined UNICODE) ? "W" : "A"

function AnimateWindow(hWnd: HWND; dwTime: DWORD; dwFlags: DWORD): Boolean;
external 'AnimateWindow@user32 stdcall';
function LoadLibraryEx(lpFileName: String; hFile: THandle; dwFlags: DWORD): THandle; external 'LoadLibraryEx{#A}@kernel32.dll stdcall';
function LoadString(hInstance: THandle; uID: SmallInt; var lpBuffer: Char; nBufferMax: Integer): Integer; external 'LoadString{#A}@user32.dll stdcall';
function SHGetNewLinkInfo(pszLinkTo, pszDir: String; var pszName: Char; var pfMustCopy: Longint; uFlags: UINT): BOOL; external 'SHGetNewLinkInfo{#A}@shell32.dll stdcall';
function PinToTaskbar(const szFilename: String; IsPin: Boolean): Boolean;

var
hInst: THandle;
buf: array [0..255] of Char;
i, res: Integer;
strLnk, strVerb: String;
objShell, colVerbs: Variant;
begin
Result := False;
if (GetWindowsVersion < $06010000) or not FileExists(szFilename) then Exit; { below Windows 7 }

{ String resources }
if IsPin then
begin
if SHGetNewLinkInfo(szFilename, ExpandConstant('{tmp}'), buf[0], res, 0) then
begin
while buf[Length(strLnk)] <> #0 do Insert(buf[Length(strLnk)], strLnk, Length(strLnk)+1);
if FileExists(ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\') + ExtractFileName(strLnk)) then Exit;
end;
res := 5386; { Pin to Tas&kbar }
end else res := 5387; { Unpin from Tas&kbar }

{ Load string resource }
hInst := LoadLibraryEx(ExpandConstant('{sys}\shell32.dll'), 0, LOAD_LIBRARY_AS_DATAFILE);
if hInst <> 0 then
try
for i := 0 to LoadString(hInst, res, buf[0], 255)-1 do Insert(buf[i], strVerb, i+1);
try
objShell := CreateOleObject('Shell.Application');
colVerbs := objShell.Namespace(ExtractFileDir(szFilename)).ParseName(ExtractFileName(szFilename)).Verbs;
for i := 1 to colVerbs.Count do if CompareText(colVerbs.Item[i].Name, strVerb) = 0 then
begin
colVerbs.Item[i].DoIt;
Result := True;
Break;
end;
except
Exit;
end;
finally
FreeDLL(hInst);
end;
end;

type
TTimerProc = procedure(HandleW, Msg, idEvent, TimeSys: LongWord);
var
PercentsTimer: LongWord;
PercentsLabel: TLabel;

function GetWindowLong(hWnd: HWND; nIndex: Integer): Longint; external 'GetWindowLongA@user32.dll stdcall delayload';
function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
function SetLayeredWindowAttributes(hwnd: HWND; crKey: TColor; bAlpha: BYTE; dwFlags: DWORD): Boolean; external 'SetLayeredWindowAttributes@user32.dll stdcall';
function CallBackProc(P:TPBProc;ParamCount:integer):LongWord; external 'wrapcallbackaddr@files:CallbackCtrl.dll stdcall';
function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint; external 'CallWindowProcA@user32.dll stdcall';
function GetTickCount: DWORD; external 'GetTickCount@kernel32.dll stdcall';
function WrapTimerProc(callback: TTimerProc; Paramcount: Integer): longword; external 'wrapcallback@files:innocallback.dll stdcall';
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): longword; external 'SetTimer@user32';
function KillTimer(hWnd, nIDEvent: LongWord): LongWord; external 'KillTimer@user32 stdcall delayload';

procedure EnableTransparencyOnDrag(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.message = WM_NCLBUTTONDOWN) and (Msg.wParam = HTCAPTION) then
begin
SetWindowLong(WizardForm.Handle, GWL_EXSTYLE, GetWindowLong(WizardForm.Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(WizardForm.Handle, 0, (255 * TransparentPercent) / 100, LWA_ALPHA);
Handled := False;
end;
if Msg.message = WM_NCMOUSEMOVE then
begin
SetWindowLong(WizardForm.Handle, GWL_EXSTYLE, GetWindowLong(WizardForm.Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(WizardForm.Handle, 0, 255, LWA_ALPHA);
Handled := False;
end;
end;

function LongintToStringTime(t:Longint):string;
var
h,m,s:integer;
begin
h:=t div 3600;
t:=t-h*3600;
m:=t div 60;
s:=t-m*60;
Result:='';
if h>0 then Result:=Result+IntToStr(h)+' ÷. ';
if (m>0) or (h>0) then Result:=Result+IntToStr(m)+' ìèí. ';
if (m>0) or (h>0) or (s>0) then Result:=Result+IntToStr(s)+' ñåê.';
end;

function PBProc(h:hWnd;Msg,wParam,lParam:Longint):Longint;
var
lt:Longint;
dt,at,pr,i1,i2:Extended;
p:string;
tc:DWORD;
begin
Result:=CallWindowProc(PBOldProc,h,Msg,wParam,lParam);
if (Msg=$402) and (WizardForm.ProgressGauge.Position>WizardForm.ProgressGauge.Min) then begin
i1:=WizardForm.ProgressGauge.Position-WizardForm.ProgressGauge.Min;
i2:=WizardForm.ProgressGauge.Max-WizardForm.ProgressGauge.Min;

tc:=GetTickCount;
if (tc-eTime)>=1000 then begin //???????????? ????? ?????????? ?? ????? ????????? ?? ????, ??? ??? ? 1 ???????
dt:=(tc-sTime)/1000;
at:=i2*dt/i1;
lt:=Round(at-dt)
TimeLeftLabel.Caption:='Îñòàëîñü - '+LongintToStringTime(lt);
eTime:=tc;
end;

pr:=i1*100/i2;
p:=' - ['+Format('%f',[pr])+'%]';
StringChange(p,',','.');
end;
end;

procedure AllCancel;
begin
SetWindowLong(WizardForm.ProgressGauge.Handle,-4,PBOldProc);
TimeLeftLabel.Free;
end;

function InitializeSetup:boolean;
begin
ExtractTemporaryFile('steam.cjstyles');
if not FileExists(ExpandConstant('{tmp}\CallbackCtrl.dll')) then ExtractTemporaryFile('CallbackCtrl.dll');
LoadSkin(ExpandConstant('{tmp}')+'\steam.cjstyles', '');
Result:=True;
end;

Function NumToStr(Float: Extended): String;
Begin
Result:= Format('%.1n', [Float]); StringChange(Result, ',', '.');
while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
SetLength(Result, Length(Result)-1);
End;

Procedure PercentsProc(h, msg, idevent, dwTime: Longword);
Begin
with WizardForm.ProgressGauge do
begin
PercentsLabel.Caption:= 'Âûïîëíåíî ' + NumToStr((Position*100)/Max) + ' %';
end;
End;

const
Indent=25;

function ssInitialize(hParent:HWND;ssTimeShow:integer;FadeOut:boolean;StretchMode:integer;BkgColor:DWORD):boo lean; external 'ssInitialize@files:isgsg.dll stdcall delayload';
procedure ssDeInitialize; external 'ssDeInitialize@files:isgsg.dll stdcall delayload';
procedure ssSetBkgImage(FileName:PChar); external 'ssSetBkgImage@files:isgsg.dll stdcall delayload';
procedure ssAddImage(FileName:PChar); external 'ssAddImage@files:isgsg.dll stdcall delayload';
procedure ssStartShow; external 'ssStartShow@files:isgsg.dll stdcall delayload';
procedure ssStopShow; external 'ssStopShow@files:isgsg.dll stdcall delayload';
procedure ShowSplashScreen(p1:HWND;p2:string;p3,p4,p5,p6,p7:integer;p8:boolean;p9:Cardinal;p10:integer); external 'ShowSplashScreen@files:isgsg.dll stdcall delayload';
function GetSystemMetrics(nIndex:Integer):integer; external 'GetSystemMetrics@user32.dll stdcall delayload';

procedure RunListClickCheck(Sender: TObject);
var
i:integer;
begin
if WizardForm.RunList.Checked[WizardForm.RunList.ItemIndex] then begin
for i:=0 to WizardForm.RunList.Items.Count-1 do
WizardForm.RunList.Checked[i]:=False;
WizardForm.RunList.Checked[WizardForm.RunList.ItemIndex]:=True;
end;
end;

procedure InitializeWizard();
begin
Application.OnMessage:=@EnableTransparencyOnDrag;
begin
ComponentPage := CreateCustomPage(wpInfoBefore, 'Âûáîð âåðñèè èãðû', 'Ïîæàëóéñòà, ñäåëàéòå âûáîð ïåðåä òåì, êàê ïðîäîëæèòü.');

{ InstallGroupBox }
InstallGroupBox := TNewGroupBox.Create(WizardForm);
with InstallGroupBox do
begin
Parent := ComponentPage.Surface;
SetBounds(ScaleX(0),ScaleY(0),ScaleX(63),ScaleY(70));
Caption := 'Version:';
end;

{ Installer }
Installer := TNewRadioButton.Create(WizardForm);
with Installer do
begin
Parent := ComponentPage.Surface;
SetBounds(ScaleX(9),ScaleY(19),ScaleX(45),ScaleY(17));
Caption := '32-bit';
end;

{ Portable }
Portable := TNewRadioButton.Create(WizardForm);
with Portable do
begin
Parent := ComponentPage.Surface;
SetBounds(ScaleX(9),ScaleY(43),ScaleX(45),ScaleY(17));
Caption := '64-bit';
Checked := True;
end;
begin
ExtractTemporaryFile('Bass.dll');
ExtractTemporaryFile('botva2.dll');
ExtractTemporaryFile('volmax.png');
ExtractTemporaryFile('volmin.png');
ExtractTemporaryFile('volpb.png');
ExtractTemporaryFile('voldote.png');
ExtractTemporaryFile('Music.mp3');
ExtractTemporaryFile('MusicButton.png');
ExtractTemporaryFile('EG.png');

ShowSplashScreen(WizardForm.Handle,ExpandConstant('{tmp}')+'\EG.png',5000,4000,3000,0,255,False,$FFF FFF,10);
ssInitialize(GetWindowLong(MainForm.Handle,-8),18,True,2,$FF000000);

WizardForm.RunList.OnClickCheck:=@RunListClickCheck;
BASS_Init('{tmp}\Music.mp3')
BASS_CreateMediaPlayer(WizardForm, '{tmp}\volmax.png', '{tmp}\volmin.png', '{tmp}\volpb.png', '{tmp}\voldote.png', 20, 325)
BASS_Initialized := True;
ExtractTemporaryFile('0.png');
ssSetBkgImage(ExpandConstant('{tmp}')+'\0.png');
WizardForm.TypesCombo.ItemIndex:=0;

PercentsLabel:= TLabel.Create(WizardForm);
with PercentsLabel do
begin
Left:= WizardForm.ProgressGauge.Left;
Top:= WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + ScaleY(10);
Width:= WizardForm.StatusLabel.Width;
Height:= WizardForm.StatusLabel.Height;
AutoSize:= False;
Transparent := True;
Parent:= WizardForm.InstallingPage;
end;
end;
end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var Version: TWindowsVersion;
begin
GetWindowsVersionEx(Version);
if (CurStep = ssPostInstall) and Version.NTPlatform and (Version.Major > 5) then begin
GDFInstall('{#GDFBinary}', '{#GDFExe}');
win7fix;
end;
begin
case CurStep of
ssInstall: begin
TimeLeftLabel:=TLabel.Create(nil);
with TimeLeftLabel do begin
Parent:=WizardForm.InstallingPage;
AutoSize:=True;
SetBounds(WizardForm.ProgressGauge.Left + ScaleX(250),WizardForm.ProgressGauge.Top + ScaleY(30),ScaleY(80),ScaleY(21));
end;
sTime:=GetTickCount;
eTime:=sTime;

PBOldProc:=SetWindowLong(WizardForm.ProgressGauge.Handle,-4,CallBackProc(@PBProc,4));
end;
ssPostInstall: AllCancel;
end;
begin
if CurStep=ssInstall then begin
ExtractTemporaryFile('1.png');
ssAddImage(ExpandConstant('{tmp}')+'\1.png');
ExtractTemporaryFile('2.png');
ssAddImage(ExpandConstant('{tmp}')+'\2.png');
ExtractTemporaryFile('3.png');
ssAddImage(ExpandConstant('{tmp}')+'\3.png');
ExtractTemporaryFile('4.png');
ssAddImage(ExpandConstant('{tmp}')+'\4.png');
ExtractTemporaryFile('5.png');
ssAddImage(ExpandConstant('{tmp}')+'\5.png');
ExtractTemporaryFile('6.png');
ssAddImage(ExpandConstant('{tmp}')+'\6.png');
ExtractTemporaryFile('7.png');
ssAddImage(ExpandConstant('{tmp}')+'\7.png');;
ExtractTemporaryFile('8.png');
ssAddImage(ExpandConstant('{tmp}')+'\8.png');
ExtractTemporaryFile('9.png');
ssAddImage(ExpandConstant('{tmp}')+'\9.png');
ExtractTemporaryFile('10.png');
ssAddImage(ExpandConstant('{tmp}')+'\10.png');
PercentsTimer:= SetTimer(0, 0, 100, WrapTimerProc(@PercentsProc, 4));
ExtractTemporaryFile('0.png');
ssAddImage(ExpandConstant('{tmp}')+'\0.png');
ssStartShow;
end;
if CurStep=ssPostInstall then ssStopShow;
end;
end;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
case CurPageID of
wpFinished: end
if IsTaskSelected('Pin') then
PinToTaskbar(ExpandConstant('{app}\Eternal Darkness-Sanitys Requiem.exe'), True);
if CurPageID=wpInstalling then begin;
WizardForm.MainPanel.Visible:=False;
WizardForm.Bevel1.Visible:=False;
WizardForm.Width:=ScaleX(395);
WizardForm.Height:=ScaleY(142);
WizardForm.Left:=ScaleX(GetSystemMetrics(0)-WizardForm.Width-Indent);
WizardForm.Top:=ScaleY(GetSystemMetrics(1)-WizardForm.Height-Indent);
WizardForm.InnerNotebook.Left:=ScaleX(10);
WizardForm.InnerNotebook.Top:=ScaleY(10);
WizardForm.InnerNotebook.Width:=ScaleX(370);
WizardForm.StatusLabel.Left:=ScaleX(0);
WizardForm.StatusLabel.Top:=ScaleY(0);
WizardForm.StatusLabel.Width:=WizardForm.InnerNotebook.Width;
WizardForm.FileNameLabel.Left:=ScaleX(0);
WizardForm.FileNameLabel.Top:=ScaleY(20);
WizardForm.FileNameLabel.Width:=WizardForm.InnerNotebook.Width;
WizardForm.ProgressGauge.Top:=ScaleY(40);
WizardForm.ProgressGauge.Width:=WizardForm.InnerNotebook.Width;
WizardForm.CancelButton.Left:=ScaleX(154);
WizardForm.CancelButton.Top:=ScaleY(80);
end;
if (CurPageID=wpFinished) or (CurPageID=wpInfoAfter) then begin
WizardForm.RunList.Checked[0]:=True;
if WizardForm.Width<>502 then begin
WizardForm.Visible:=False;
WizardForm.Width:=ScaleX(502);
WizardForm.Height:=ScaleY(392);
WizardForm.Left:=(GetSystemMetrics(0)-WizardForm.Width) div 2;
WizardForm.Top:=(GetSystemMetrics(1)-WizardForm.Height) div 2;
WizardForm.MainPanel.Visible:=True;
WizardForm.Bevel1.Visible:=True;
WizardForm.InnerNotebook.Left:=ScaleX(40);
WizardForm.InnerNotebook.Top:=ScaleY(72);
WizardForm.InnerNotebook.Width:=ScaleX(417);
WizardForm.Visible:=True;
end;
end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
if CurPageID=wpFinished then
begin
if WizardForm.RunList.Checked[0] then
Result := True;
end;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_OKCANCEL) = IDOK then
begin
Confirm := False;
AnimateWindow(WizardForm.Handle, 2500, AW_BLEND or AW_HIDE);
Cancel := True;
end else
Cancel := False;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
Binary: String;
GUID: TGUID;
begin
if CurUninstallStep=usUninstall then
begin
Binary:=ExpandConstant('{#GDFBinary}');
RetrieveGUIDForApplication(Binary, GUID);
RemoveFromGameExplorer(GUID);
RemoveTasks(GUID);
UnloadDll(ExpandConstant('{localappdata}\GameuxInstallHelper.dll'));
end;
begin
if (CurUninstallStep=usUninstall) then
begin
case CurUninstallStep of
usUninstall: begin
PinToTaskbar(ExpandConstant('{app}\Eternal Darkness-Sanitys Requiem.exe'), False);
end;
end;
end;
end;
end;

procedure DeinitializeSetup();
begin
if BASS_Initialized then
begin
KillTimer(0, PercentsTimer);
UnloadSkin();
ssDeInitialize;
BASS_DeInit;
gdipShutdown
end;
end;




© OSzone.net 2001-2012