Показать полную графическую версию : Скрипты Inno Setup. Помощь и советы [часть 6]
novahudonoser
15-01-2014, 23:23
КОМРАДЫ! Подскажите пожалуйста реализацию скрипта: "с возможностью обновления программы"
пример:
установщик перед началом распаковки новых файлов - проверяет не только их наличие в системе но и их состояние
в часности, та программа которую пользователь пытается обновить - уже запущена, следовательно скрипт должен отправить приложению мессагу что бы та благополучно закрылась
и только потом уже копировал файлы с заменой.
собственно интересует реализация:
1. проверяем, запущена программа или нет
2. если запущена то закрываем её
полагаю что где то рядом с [Setup]: CloseApplications
но как юзать не догнал (
novahudonoser, шапка - Ссылки на примеры скриптов: - Запущен ли процесс (WMI)/Запущен ли процесс - Закрытие процесса - изучай, применяй.
novahudonoser
16-01-2014, 00:56
пример закрытия приложения не компилится (
http://joxi.ru/y_XWUhjKTJBsG5SWhto
novahudonoser
16-01-2014, 01:20
кстати Сборник скриптов в формате chm не пашет http://joxi.ru/fvvWUhjKTJBtGxme7BI
пример закрытия приложения не компилится ( »
У вас не установлен препроцессор
PerfectLove
16-01-2014, 01:39
Помогите сделать второй чекбокс для бекапа.
[_Code]
var
MyTask: TCheckBox;
function MoveFile(const srcFile, destFile: PAnsiChar): Integer; external 'MoveFileA@kernel32.dll stdcall';
procedure CurStepChanged(CurStep: TSetupStep);
var
FindFiles: TFindRec;
i: integer;
MyFiles: array of string;
MyDir, BackDir: string;
begin
if CurStep=ssInstall then begin
if MyTask.Checked then begin
MyFiles:=['*']; // указать файлы или маски нужные для бакупа через запятую. при указании маски '*' бакупятся все файлы с вложенными папками
MyDir:=ExpandConstant('{app}'+'\'); //папка откуда бакупить
BackDir:=ExpandConstant('{app}'+'\Backup\'); // папка куда бакупить
for i:=0 to GetArrayLength(MyFiles)-1 do
begin
if FindFirst(MyDir+MyFiles[i], FindFiles) then begin
repeat
if not DirExists(BackDir) then begin
CreateDir(BackDir);
end;
MoveFile(MyDir+FindFiles.Name, BackDir+FindFiles.Name);
until not FindNext(FindFiles);
FindClose(FindFiles);
end;
end;
end;
end;
end;
procedure InitializeWizard();
begin
MyTask:=TCheckBox.Create(WizardForm);
with MyTask do
begin
Parent:=WizardForm.SelectDirPage;
Caption:='Create Backup';
Left:=ScaleX(0);
Top:=ScaleY(100);
Width:=ScaleX(400);
Height:=ScaleY(15);
TabOrder:=0;
Checked:=True;
end;
end;
http://i.imgur.com/o4x5oSa.png
Помогите сделать второй чекбокс для бекапа. »
Не уловил суть. Просто второй чекбокс? Пожалуйста, здесь массив чекбоксов с двумя элементами. Действие назначено только для чекбокса с индексом 0(arrayChkBox[0]):
[Code]
#define A = (Defined UNICODE) ? "W" : "A"
function MoveFile(const srcFile, destFile: PAnsiChar): Integer; external 'MoveFile{#A}@kernel32.dll stdcall';
var
arrayChkBox: array of TCheckBox;
procedure CreateChkBox();
var
i, Len: Integer;
begin
SetArrayLength(arrayChkBox, 2);
Len := GetArrayLength(arrayChkBox) - 1;
for i := 0 to Len do
begin
arrayChkBox[i] := TCheckBox.Create(nil);
with arrayChkBox[i] do
begin
Parent := WizardForm.SelectDirPage;
SetBounds(ScaleX(0), ScaleY(115 + i*20), ScaleX(400), ScaleY(15));
Checked := True;
case i of
0: Caption := 'Create Backup';
Len: Caption := 'Create Backup 2';
end;
end;
end;
end;
procedure InitializeWizard();
begin
CreateChkBox();
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
FindFiles: TFindRec;
i: Integer;
MyFiles: array of string;
MyDir, BackDir: string;
begin
case CurStep of
ssInstall:
begin
if arrayChkBox[0].Checked then
begin
MyFiles := ['*'];
MyDir := ExpandConstant('{app}' + '\');
BackDir := ExpandConstant('{app}' + '\Backup\');
for i := 0 to GetArrayLength(MyFiles) - 1 do
begin
if FindFirst(MyDir+MyFiles[i], FindFiles) then
begin
repeat
if not DirExists(BackDir) then
begin
CreateDir(BackDir);
end;
MoveFile(MyDir + FindFiles.Name, BackDir + FindFiles.Name);
until not FindNext(FindFiles);
FindClose(FindFiles);
end;
end;
end;
end;
end;
end;
И пример попроще, без массива. Действие назначено только для чекбокса MyTask:
[Code]
#define A = (Defined UNICODE) ? "W" : "A"
function MoveFile(const srcFile, destFile: PAnsiChar): Integer; external 'MoveFile{#A}@kernel32.dll stdcall';
var
MyTask, MyTask2: TCheckBox;
procedure CreateChkBox();
begin
MyTask := TCheckBox.Create(nil);
with MyTask do
begin
Parent := WizardForm.SelectDirPage;
SetBounds(ScaleX(0), ScaleY(115), ScaleX(400), ScaleY(15));
Caption := 'Create Backup';
Checked := True;
end;
MyTask2 := TCheckBox.Create(nil);
with MyTask2 do
begin
Parent := WizardForm.SelectDirPage;
SetBounds(ScaleX(0), ScaleY(MyTask.Top + 20), ScaleX(400), ScaleY(15));
Caption := 'Create Backup2';
Checked := True;
end;
end;
procedure InitializeWizard();
begin
CreateChkBox();
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
FindFiles: TFindRec;
i: Integer;
MyFiles: array of string;
MyDir, BackDir: string;
begin
case CurStep of
ssInstall:
begin
if MyTask.Checked then
begin
MyFiles := ['*'];
MyDir := ExpandConstant('{app}' + '\');
BackDir := ExpandConstant('{app}' + '\Backup\');
for i := 0 to GetArrayLength(MyFiles) - 1 do
begin
if FindFirst(MyDir+MyFiles[i], FindFiles) then
begin
repeat
if not DirExists(BackDir) then
begin
CreateDir(BackDir);
end;
MoveFile(MyDir + FindFiles.Name, BackDir + FindFiles.Name);
until not FindNext(FindFiles);
FindClose(FindFiles);
end;
end;
end;
end;
end;
end;
P. S.
На форуме полно примеров, как создать кастомный чекбокс.
PerfectLove
16-01-2014, 04:59
Не уловил суть. »
Виноват, мой косяк что не уточнил. На данный момент первый чекбокс делает бекап всей папки. Хочу добавить второй чекбокс чтобы делать бекап только нескольких файлов а не всей папки.
На данный момент первый чекбокс делает бекап всей папки. Хочу добавить второй чекбокс чтобы делать бекап только нескольких файлов а не всей папки. »
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program\Fonts
OutputDir=.
[Files]
Source: C:\Windows\Fonts\*; DestDir: {app}; Flags: external overwritereadonly ignoreversion;
[Code]
#define A = (Defined UNICODE) ? "W" : "A"
function MoveFile(const srcFile, destFile: PAnsiChar): Integer; external 'MoveFile{#A}@kernel32.dll stdcall';
var
arrayChk: array of TCheckBox;
function ChkChecked(const Index: Integer): Boolean;
var
Len: Integer;
begin
Len := GetArrayLength(arrayChk) - 1;
if Index > Len then Exit;
Result := arrayChk[Index].Checked;
end;
procedure CreateBackup();
var
FindFiles: TFindRec;
i, Len: Integer;
MyFiles: array of string;
MyDir, BackDir: string;
begin
Len := GetArrayLength(arrayChk) - 1;
if (ChkChecked(0) and ChkChecked(Len)) then Exit; //Если выбраны оба чекбокса резервная копия создана не будет
if ChkChecked(0) then MyFiles := ['*']; //Резервное копирование папки
if ChkChecked(Len) then MyFiles := ['ariali.ttf', 'tahoma.ttf', 'verdana.ttf']; //Резервное копирование определенных файлов
MyDir := ExpandConstant('{app}' + '\');
BackDir := ExpandConstant('{app}' + '\Backup\');
for i := 0 to GetArrayLength(MyFiles) - 1 do
begin
if FindFirst(MyDir + MyFiles[i], FindFiles) then
begin
repeat
if not DirExists(BackDir) then
begin
CreateDir(BackDir);
end;
MoveFile(MyDir + FindFiles.Name, BackDir + FindFiles.Name);
until not FindNext(FindFiles);
FindClose(FindFiles);
end;
end;
end;
procedure CreateChk();
var
i, Len: Integer;
begin
SetArrayLength(arrayChk, 2);
Len := GetArrayLength(arrayChk) - 1;
for i := 0 to Len do
begin
arrayChk[i] := TCheckBox.Create(nil);
with arrayChk[i] do
begin
Parent := WizardForm.SelectDirPage;
SetBounds(ScaleX(0), ScaleY(115 + i*20), ScaleX(400), ScaleY(15));
case i of
0: Caption := 'Создать резервную копию папки';
Len: Caption := 'Создать резервную копию основных файлов';
end;
end;
end;
end;
procedure InitializeWizard();
begin
CreateChk();
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
Len: Integer;
begin
Len := GetArrayLength(arrayChk) - 1;
case CurStep of
ssInstall: if (ChkChecked(0) or ChkChecked(Len)) then CreateBackup();
end;
end;
кстати Сборник скриптов в формате chm не пашет »писали уже наверно 100500 раз - правой кнопкой по файлу - свойства - разблокировать.
PerfectLove
16-01-2014, 08:27
Тогда, наверное, будет правильней создать две радио-кнопки, »
Не совсем. Радио-кнопки будут заставлять пользователя делать бекап первого или другого варианта. Я не хочу "заставлять" делать бекап. Чекбоксы подойдут лучше а возможность вибирать два варианта одновременно будет уже на совести пользавтела так как изначально чекбоксы не будут выбраны
Чекбоксы подойдут лучше »
Исправленный пример в моем предыдущем посте http://forum.oszone.net/post-2290032-1849.html
novahudonoser
16-01-2014, 14:44
У вас не установлен препроцессор »
Вы извините, я со скриптами дела не имел, поставил сейчас ispack-5.5.4.exe в составе которого идёт этот препроцессор и Inno Script Studio
однако код не компилится http://joxi.ru/RsHXUv3JTJAILoANWhM
[Setup]
AppName=My_programm 1.7
AppVerName=My_programm
AppVersion=1.7
OutputDir=output\
OutputBaseFilename=My_programm_1.7
DefaultDirName={pf}\My_programm
AllowNoIcons=yes
DefaultGroupName=My_programm
DisableStartupPrompt=yes
DisableReadyPage=yes
Compression=lzma
SolidCompression=yes
#define A = (Defined UNICODE) ? "W" : "A"
const
TH32CS_SNAPPROCESS = $2;
INVALID_HANDLE_VALUE = -1;
PROCESS_TERMINATE = $1;
PROCESS_CREATE_THREAD = $2;
PROCESS_VM_OPERATION = $8;
PROCESS_VM_READ = $10;
PROCESS_VM_WRITE = $20;
PROCESS_QUERY_INFORMATION = $400;
SYNCHRONIZE = $100000;
MEM_COMMIT = $1000;
MEM_RESERVE = $2000;
PAGE_EXECUTE_READWRITE = $40;
TOKEN_QUERY = $8;
TOKEN_ADJUST_PRIVILEGES = $20;
SE_PRIVILEGE_ENABLED = $2;
MAX_PATH = 260;
TA_FAILED = 0;
TA_SUCCESS_CLEAN = 1;
TA_SUCCESS_KILL = 2;
WM_CLOSE = $10;
WAIT_OBJECT_0 = $0;
WAIT_TIMEOUT = $102;
type
TPROCESSENTRY32 = record
dwSize, cntUsage, th32ProcessID: DWORD;
th32DefaultHeapID: Longint;
th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array [0..259] of Char;
end;
LUID = record
LowPart: DWORD;
HighPart: Longint;
end;
LUID_AND_ATTRIBUTES = record
Luid: LUID;
Attributes: DWORD;
end;
TOKEN_PRIVILEGES = record
PrivilegeCount: DWORD;
Privileges: array [0..0] of LUID_AND_ATTRIBUTES;
end;
function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
#ifdef UNICODE
function Process32First(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32First{#A}@kernel32.dll stdcall';
function Process32Next(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32Next{#A}@kernel32.dll stdcall';
#else
function Process32First(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32First@kernel32.dll stdcall';
function Process32Next(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32Next@kernel32.dll stdcall';
#endif
function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; external 'OpenProcess@kernel32.dll stdcall';
function OpenProcessToken(ProcessHandle: THandle; DesiredAccess: DWORD; var TokenHandle: THandle): BOOL; external 'OpenProcessToken@advapi32.dll stdcall';
function GetCurrentProcess(): THandle; external 'GetCurrentProcess@kernel32.dll stdcall';
function LookupPrivilegeValue(lpSystemName, lpName: String; var lpLuid: LUID): BOOL; external 'LookupPrivilegeValue{#A}@advapi32.dll stdcall';
function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL; NewState: TOKEN_PRIVILEGES; BufferLength: DWORD; var PreviousState: TOKEN_PRIVILEGES; var ReturnLength: Longint): BOOL; external 'AdjustTokenPrivileges@advapi32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';
function GetProcessImageFileName(hProcess: THandle; var lpImageFileName: Char; nSize: DWORD): DWORD; external 'GetProcessImageFileName{#A}@psapi.dll stdcall';
function QueryDosDevice(lpDeviceName: String; var lpTargetPath: Char; ucchMax: DWORD): DWORD; external 'QueryDosDevice{#A}@kernel32.dll stdcall';
function EnumWindows(lpEnumFunc, lParam: Longint): BOOL; external 'EnumWindows@user32.dll stdcall';
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; external 'WaitForSingleObject@kernel32.dll stdcall';
function GetProcAddress(hModule: THandle; lpProcName: String): Longint; external 'GetProcAddress@kernel32.dll stdcall';
function GetModuleHandle(lpModuleName: String): THandle; external 'GetModuleHandle{#A}@kernel32.dll stdcall';
function VirtualAllocEx(hProcess: THandle; lpAddress, dwSize: Longint; flAllocationType, flProtect: DWORD): Longint; external 'VirtualAllocEx@kernel32.dll stdcall';
function WriteProcessMemory(hProcess: THandle; lpBaseAddress, lpBuffer, nSize: Longint; var lpNumberOfBytesWritten: Longint): BOOL; external 'WriteProcessMemory@kernel32.dll stdcall';
function CreateRemoteThread(hProcess: THandle; lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; external 'CreateRemoteThread@kernel32.dll stdcall';
function TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL; external 'TerminateProcess@kernel32.dll stdcall';
function GetWindowThreadProcessId(hWnd: HWND; var lpdwProcessId: DWORD): DWORD; external 'GetWindowThreadProcessId@user32.dll stdcall';
/////////////////////////////////////////////////////////
function CharArrayToString(aChar: array of Char): String;
begin
Result := '';
while aChar[Length(Result)] <> #0 do Insert(aChar[Length(Result)], Result, Length(Result)+1);
end;
////////////////////////////////////////////////////////////
function EnumWindowsProc(hwnd: HWND; lParam: Longint): BOOL;
var
dwID: DWORD;
begin
GetWindowThreadProcessId(hwnd, dwID);
if dwID = lParam then PostMessage(hwnd, WM_CLOSE, 0, 0);
Result := True;
end;
////////////////////////////////////////////////////////////////////////
function TerminateApp(const szProcess: String; dwTimeout: DWORD): DWORD;
var
hProcessSnap, hProc, hToken, hThread, lpProcName: THandle;
pe32: TPROCESSENTRY32;
aBuf: array [0..259] of Char;
szFileName, szDeviceName: String;
tkp: TOKEN_PRIVILEGES;
SeDebugNameValue: LUID;
i, lpMemory, ret: Longint;
lpThreadId, dwDrives: DWORD;
begin
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
try
pe32.dwSize := SizeOf(pe32);
if not Process32First(hProcessSnap, pe32) then Exit;
while Process32Next(hProcessSnap, pe32) do
begin
if CompareText(CharArrayToString(pe32.szExeFile), ExtractFileName(szProcess)) <> 0 then Continue;
// try open process
hProc := OpenProcess(PROCESS_TERMINATE or PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION or SYNCHRONIZE, False, pe32.th32ProcessID);
if hProc = TA_FAILED then
begin
// open process token adjust privileges
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then Exit;
if not LookupPrivilegeValue('', 'SeDebugPrivilege', SeDebugNameValue) then Exit;
try
// fill token privileges struct
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := SeDebugNameValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
// set debug privileges
if not AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ret) then Exit;
// try open process with debug privileges
hProc := OpenProcess(PROCESS_TERMINATE or PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION or SYNCHRONIZE, False, pe32.th32ProcessID);
if hProc = TA_FAILED then Exit;
finally
tkp.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ret);
CloseHandle(hToken);
end;
end;
// if szProcess is full path
if CompareText(szProcess, ExtractFileName(szProcess)) <> 0 then
begin
GetProcessImageFileName(hProc, aBuf[0], SizeOf(aBuf));
szFileName := CharArrayToString(aBuf);
dwDrives := GetLogicalDrives();
for i := 2 to 25 do if dwDrives and (1 shl i) <> 0 then
begin
QueryDosDevice(Format('%s:', [Chr(Ord('A') + i)]), aBuf[0], SizeOf(aBuf));
szDeviceName := CharArrayToString(aBuf);
if Pos(szDeviceName, szFileName) = 0 then Continue;
StringChangeEx(szFileName, szDeviceName, Format('%s:', [Chr(Ord('A') + i)]), True);
if CompareText(szProcess, szFileName) = 0 then Break;
end;
if CompareText(szProcess, szFileName) <> 0 then
begin
CloseHandle(hProc);
Continue;
end;
end;
// try stop process
try
EnumWindows(CallbackAddr('EnumWindowsProc'), pe32.th32ProcessID);
case WaitForSingleObject(hProc, dwTimeout) of
WAIT_OBJECT_0: Result := TA_SUCCESS_CLEAN;
WAIT_TIMEOUT: try
lpProcName := GetProcAddress(GetModuleHandle('kernel32.dll'), 'ExitProcess');
if lpProcName = 0 then Exit;
//
lpMemory := VirtualAllocEx(hProc, 0, SizeOf(lpProcName), MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if not WriteProcessMemory(hProc, lpMemory, lpProcName, SizeOf(lpProcName), ret) then Exit;
//
hThread := CreateRemoteThread(hProc, 0, 0, lpMemory, 0, 0, lpThreadId);
if hThread > 0 then
case WaitForSingleObject(hThread, dwTimeout) of
WAIT_OBJECT_0: Result := TA_SUCCESS_CLEAN;
WAIT_TIMEOUT: if TerminateProcess(hProc, 0) then Result := TA_SUCCESS_KILL;
end;
finally
CloseHandle(hThread);
end;
end;
finally
CloseHandle(hProc);
if CompareText(szProcess, ExtractFileName(szProcess)) <> 0 then Exit;
end;
end;
finally
CloseHandle(hProcessSnap);
end;
end;
/////////////////////////////
procedure InitializeWizard();
begin
TerminateApp('calc.exe', 5000);
end;
novahudonoser
[code] должно стоять
#define A = (Defined UNICODE) ? "W" : "A"
novahudonoser
16-01-2014, 16:51
ой, [code] я забыл поставить да
только ошибки не кончаются (
http://joxi.ru/stXXUv3JTJAALiyxiR0
походу это стандартная win32 функция
не знаю как inno подключает win32 api
возможно, необходим некий "include", "import", "using" или что-то подобное
подскажите братцы
novahudonoser
[code]
function GetLogicalDrives: DWord; external 'GetLogicalDrives@kernel32.dll stdcall';
novahudonoser
16-01-2014, 18:14
http://joxi.ru/EenXUv3JTJDlct1uZX4
я уже не уверен что это вообще заработает
может ктонить запустить у себя проверить что не так с этим кодом?
Не срабатывает кнопка отмены во время распаковки файлов помогите весь код просмотрел так и не нашол причину
const
PCFonFLY=true;
notPCFonFLY=false;
var
Enabled: Boolean;
hCancelBtn, hNextBtn, hBackBtn, hDirBrowseBtn, hGroupBrowseBtn: HWND;
Welcomelbl1, Selectlbl1, Selectlbl2, MainLabel, Mb1, Mb2, NoIconsLabel, islbl1, islbl2, islbl3: TLabel;
WFButtonFont: TFont;
form, form1: Longint;
NoIconsCheck: TNewCheckBox;
IntList, VoiceList: TNewCheckListBox;
ISDoneCancel: Integer;
ISDoneError: Boolean;
PCFVer: Double;
s: AnsiString;
InputPage: TInputQueryWizardPage;
CaptionLabel: TLabel;
function ReleaseCapture: Longint; external 'ReleaseCapture@user32.dll stdcall';
procedure LabelOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
SendMessage(WizardForm.Handle, $0112, $F012, 0)
end;
#include "AddIss\botva2.iss"
#include "AddIss\progressbar.iss"
var
ISDonePB: TImgPB;
function InitializeSetup:boolean;
begin
if not FileExists(ExpandConstant('{tmp}\botva2.dll')) then ExtractTemporaryFile('botva2.dll');
if not FileExists(ExpandConstant('{tmp}\b2p.dll')) then ExtractTemporaryFile('b2p.dll');
Result:=True;
end;
function cm(s: PAnsiChar): String;
begin
Result:= ExpandConstant('{cm:'+s+'}');
end;
///////////////////////////////////////////////////////////////////////////////////////////////////
type
TCallback = function (OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;
function WrapCallback(callback:TCallback; paramcount:integer):longword;external 'wrapcallback@files:ISDone.dll stdcall delayload';
function ISArcExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath, ExtractedPath: AnsiString; DeleteInFile:boolean; Password, CfgFile, WorkPath: AnsiString; ExtractPCF: boolean ):boolean; external 'ISArcExtract@files:ISDone.dll stdcall delayload';
function IS7ZipExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath: AnsiString; DeleteInFile:boolean; Password: AnsiString):boolean; external 'IS7zipExtract@files:ISDone.dll stdcall delayload';
function ISRarExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutPath: AnsiString; DeleteInFile:boolean; Password: AnsiString):boolean; external 'ISRarExtract@files:ISDone.dll stdcall delayload';
function ISPrecompExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutFile: AnsiString; DeleteInFile:boolean):boolean; external 'ISPrecompExtract@files:ISDone.dll stdcall delayload';
function ISSRepExtract(CurComponent:Cardinal; PctOfTotal:double; InName, OutFile: AnsiString; DeleteInFile:boolean):boolean; external 'ISSrepExtract@files:ISDone.dll stdcall delayload';
function ISxDeltaExtract(CurComponent:Cardinal; PctOfTotal:double; minRAM,maxRAM:integer; InName, DiffFile, OutFile: AnsiString; DeleteInFile, DeleteDiffFile:boolean):boolean; external 'ISxDeltaExtract@files:ISDone.dll stdcall delayload';
function ISPackZIP(CurComponent:Cardinal; PctOfTotal:double; InName, OutFile: AnsiString;ComprLvl:integer; DeleteInFile:boolean):boolean; external 'ISPackZIP@files:ISDone.dll stdcall delayload';
function ShowChangeDiskWindow(Text, DefaultPath, SearchFile:AnsiString):boolean; external 'ShowChangeDiskWindow@files:ISDone.dll stdcall delayload';
function Exec2 (FileName, Param: PAnsiChar;Show:boolean):boolean; external 'Exec2@files:ISDone.dll stdcall delayload';
function ISFindFiles(CurComponent:Cardinal; FileMask:AnsiString; var ColFiles:integer):integer; external 'ISFindFiles@files:ISDone.dll stdcall delayload';
function ISPickFilename(FindHandle:integer; OutPath:AnsiString; var CurIndex:integer; DeleteInFile:boolean):boolean; external 'ISPickFilename@files:ISDone.dll stdcall delayload';
function ISGetName(TypeStr:integer):PAnsichar; external 'ISGetName@files:ISDone.dll stdcall delayload';
function ISFindFree(FindHandle:integer):boolean; external 'ISFindFree@files:ISDone.dll stdcall delayload';
function ISExec(CurComponent:Cardinal; PctOfTotal,SpecifiedProcessTime:double; ExeName,Parameters,TargetDir,OutputStr:AnsiString;Show:boolean):boolean; external 'ISExec@files:ISDone.dll stdcall delayload';
function SrepInit(TmpPath:PAnsiChar;VirtMem,MaxSave:Cardinal):boolean; external 'SrepInit@files:ISDone.dll stdcall delayload';
function PrecompInit(TmpPath:PAnsiChar;VirtMem:cardinal;PrecompVers:single):boolean; external 'PrecompInit@files:ISDone.dll stdcall delayload';
function FileSearchInit(RecursiveSubDir:boolean):boolean; external 'FileSearchInit@files:ISDone.dll stdcall delayload';
function ISDoneInit(RecordFileName:AnsiString; TimeType,Comp1,Comp2,Comp3:Cardinal; WinHandle, NeededMem:longint; callback:TCallback):boolean; external 'ISDoneInit@files:ISDone.dll stdcall';
function ISDoneStop:boolean; external 'ISDoneStop@files:ISDone.dll stdcall';
function ChangeLanguage(Language:AnsiString):boolean; external 'ChangeLanguage@files:ISDone.dll stdcall delayload';
function SuspendProc:boolean; external 'SuspendProc@files:ISDone.dll stdcall';
function ResumeProc:boolean; external 'ResumeProc@files:ISDone.dll stdcall';
////////////////////////////////////////////////////////////////////////////////////////////////////
function ProgressCallback(OveralPct,CurrentPct: integer;CurrentFile,TimeStr1,TimeStr2,TimeStr3:PAnsiChar): longword;
begin
if OveralPct<=1000 then ImgPBSetPosition(ISDonePB, OveralPct);
WizardForm.Caption:= s + ' - ' + IntToStr(OveralPct div 10)+'.'+chr(48 + OveralPct mod 10)+'%';
islbl1.Caption:= cm('Extracted') + ' ' + IntToStr(OveralPct div 10)+'.'+chr(48 + OveralPct mod 10)+'%';
islbl2.Caption:= MinimizePathName(ExpandConstant('{app}\')+CurrentFile, islbl2.Font, ScaleX(400));
Result := ISDoneCancel;
end;
procedure CancelButtonOnClick(hBtn: HWND);
begin
SuspendProc;
if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_YESNO) = IDYES then begin
ISDoneCancel:=1;
islbl1.Caption:= cm('rbc');
end;
ResumeProc;
end;
function CheckError:boolean;
begin
Result:= not ISDoneError;
end;
//************************************************ [Начало - Загрузка изображений и подготовка визарда] ***************************************************//
procedure CreateWizardImg;
begin
with WizardForm do begin
ClientWidth:=ScaleX(623);
ClientHeight:=ScaleY(382);
InnerNotebook.Hide;
OuterNotebook.Hide;
Bevel.Hide;
Center;
Color:= $191919;
end;
ImgLoad(WizardForm.Handle, 'fon.png', ScaleX(0), ScaleY(0), WizardForm.ClientWidth, WizardForm.ClientHeight, True, True);
form:= ImgLoad(WizardForm.Handle, 'form.png', ScaleX(0), ScaleY(0), WizardForm.ClientWidth, WizardForm.ClientHeight, True, True);
form1:= ImgLoad(WizardForm.Handle, 'form1.png', ScaleX(0), ScaleY(0), WizardForm.ClientWidth, WizardForm.ClientHeight, True, True);
ImgLoad(WizardForm.Handle, 'logo.png', ScaleX(20), ScaleY(326), ScaleX(190), ScaleY(39), True, True);
ImgSetVisibility(form1, false);
ImgApplyChanges(WizardForm.Handle);
end;
//************************************************ [Конец - Загрузка изображений и подготовка визарда] ***************************************************//
//************************************************ [Начало - Текстуры кнопок] ***************************************************//
procedure SetStateNewButtons;
begin
with WizardForm.BackButton do begin
BtnSetText(hBackBtn,PAnsiChar(Caption));
BtnSetVisibility(hBackBtn,Visible);
BtnSetEnabled(hBackBtn,Enabled);
end;
with WizardForm.NextButton do begin
BtnSetText(hNextBtn,PAnsiChar(Caption));
BtnSetVisibility(hNextBtn,Visible);
BtnSetEnabled(hNextBtn,Enabled);
end;
with WizardForm.CancelButton do begin
BtnSetText(hCancelBtn,PAnsiChar(Caption));
BtnSetVisibility(hCancelBtn,Visible);
BtnSetEnabled(hCancelBtn,Enabled);
end;
BtnSetText(hDirBrowseBtn,PAnsiChar(WizardForm.DirBrowseButton.Caption));
BtnSetText(hGroupBrowseBtn,PAnsiChar(WizardForm.GroupBrowseButton.Caption));
end;
procedure WizardFormBtnClick(hBtn:HWND);
var
Btn: TButton;
begin
case hBtn of
hCancelBtn: Btn:=WizardForm.CancelButton;
hNextBtn: Btn:=WizardForm.NextButton;
hBackBtn: Btn:=WizardForm.BackButton;
hDirBrowseBtn: Btn:=WizardForm.DirBrowseButton;
hGroupBrowseBtn: Btn:=WizardForm.GroupBrowseButton;
end;
Btn.OnClick(Btn);
SetStateNewButtons;
BtnRefresh(hBtn);
end;
procedure NoIconsCheckClick(Sender: TObject);
begin
if NoIconsCheck.Checked then begin
WizardForm.GroupEdit.Enabled:= false;
WizardForm.GroupBrowseButton.Enabled:= false;
BtnSetEnabled(hGroupBrowseBtn, false);
end else begin
WizardForm.GroupEdit.Enabled:= true;
WizardForm.GroupBrowseButton.Enabled:= true;
BtnSetEnabled(hGroupBrowseBtn, true);
end;
WizardForm.NoIconsCheck.Checked:= NoIconsCheck.Checked;
WizardForm.GroupEdit.Color:= clblack;
end;
procedure NoIconsLabelClick(Sender: TObject);
begin
NoIconsCheck.Checked:= not NoIconsCheck.Checked;
NoIconsCheckClick(nil);
end;
procedure ButtonsTextures;
begin
WFButtonFont:=TFont.Create;
WFButtonFont.Style:=[fsBold];
WFButtonFont.Name:= 'Arial';
WFButtonFont.Size:= 8;
with WizardForm.BackButton do begin
hBackBtn:= BtnCreate(WizardForm.Handle, ScaleX(Left+28), ScaleY(Top+3), ScaleX(100), ScaleY(35), 'button.png', 1, False);
BtnSetEvent(hBackBtn, BtnClickEventID, CallbackAddr('WizardFormBtnClick'));
BtnSetFont(hBackBtn, WFButtonFont.Handle);
BtnSetFontColor(hBackBtn, clblack, clblack, clblack, clblack);
Width:=0;
Height:=0;
end;
with WizardForm.NextButton do begin
hNextBtn:=BtnCreate(WizardForm.Handle, ScaleX(Left+55), ScaleY(Top+3), ScaleX(100), ScaleY(35), 'button.png', 1, False);
BtnSetEvent(hNextBtn,BtnClickEventID, CallbackAddr('WizardFormBtnClick'));
BtnSetFont(hNextBtn,WFButtonFont.Handle);
BtnSetFontColor(hNextBtn, clblack, clblack, clblack, clblack);
Width:=0;
Height:=0;
end;
with WizardForm.CancelButton do begin
hCancelBtn:=BtnCreate(WizardForm.Handle, ScaleX(Left+85), ScaleY(Top+3), ScaleX(100), ScaleY(35), 'button.png', 1, False);
BtnSetEvent(hCancelBtn,BtnClickEventID, CallbackAddr('WizardFormBtnClick'));
BtnSetFont(hCancelBtn,WFButtonFont.Handle);
BtnSetFontColor(hCancelBtn, clblack, clblack, clblack, clblack);
Width:=0;
Height:=0;
end;
with WizardForm.DirBrowseButton do begin
hDirBrowseBtn:=BtnCreate(WizardForm.Handle, ScaleX(Left+90), ScaleY(Top+164), ScaleX(100), ScaleY(35), 'button.png', 1, False);
BtnSetEvent(hDirBrowseBtn,BtnClickEventID, CallbackAddr('WizardFormBtnClick'));
BtnSetFont(hDirBrowseBtn,WFButtonFont.Handle);
BtnSetFontColor(hDirBrowseBtn, clblack, clblack, clblack, clblack);
Width:=0;
Height:=0;
end;
with WizardForm.GroupBrowseButton do begin
hGroupBrowseBtn:=BtnCreate(WizardForm.Handle, ScaleX(Left+90), ScaleY(Top+164), ScaleX(100), ScaleY(35), 'button.png', 1, False);
BtnSetEvent(hGroupBrowseBtn,BtnClickEventID, CallbackAddr('WizardFormBtnClick'));
BtnSetFont(hGroupBrowseBtn,WFButtonFont.Handle);
BtnSetFontColor(hGroupBrowseBtn, clblack, clblack, clblack, clblack);
Width:=0;
Height:=0;
end;
end;
//************************************************ [Конец - Текстуры кнопок] ***************************************************//
//************************************************ [Начало - Место на жестком диске] ***************************************************//
function NumToStr(Float: Extended): string;
begin
Result:=Format('%.2n', [Float]);
StringChange(Result, ',', '.');
while ((Result[Length(Result)]='0') or (Result[Length(Result)]='.')) and (Pos('.',Result)>0) do SetLength(Result,Length(Result)-1);
end;
function MbOrTB(Float: Extended): string;
begin
if Float<1024 then Result:=NumToStr(Float)+' MB'
else if (Float/1024)<1024 then Result:=NumToStr(Float/1024)+' GB'
else if (Float/(1024*1024))<1024 then Result:=NumToStr(Float/(1024*1024))+' TB'
end;
procedure GetFreeSpaceCaption(Sender: TObject);
var
Enable: Boolean;
Path: AnsiString;
FreeMB, TotalMB: Cardinal;
begin
Path:= ExtractFileDrive(WizardForm.DirEdit.Text);
Enable:= GetSpaceOnDisk(Path, True, FreeMB, TotalMB);
if not Enable then begin
mb1.Caption:= cm('FreeSpace') + ' ' + '0 Мб';
mb2.Caption:= cm('NeedSpace') + ' ' + MborTb({#NeedSize});
WizardForm.NextButton.Enabled:= false;
BtnSetEnabled(hNextBtn, false);
Exit;
end;
if Enable then begin
mb1.Caption:= cm('FreeSpace') + ' ' + MbOrTb(FreeMB);
mb2.Caption:= cm('NeedSpace') + ' ' + MborTb({#NeedSize});
WizardForm.NextButton.Enabled:= true;
BtnSetEnabled(hNextBtn, true);
end;
if FreeMB < {#NeedSize} then begin WizardForm.NextButton.Enabled:= false; BtnSetEnabled(hNextBtn, false); end else begin WizardForm.NextButton.Enabled:= true; BtnSetEnabled(hNextBtn, true); end;
end;
//************************************************ [Конец - Место на жестком диске] ***************************************************//
//************************************************ [Начало - Создание лебелов] ***************************************************//
procedure CreateLabel;
begin
Welcomelbl1:= TLabel.Create(WizardForm);
with Welcomelbl1 do
begin
Left:= ScaleX(80);
Top:= ScaleY(244);
Width:= ScaleX(450);
Height:= ScaleY(450);
AutoSize:= false;
Transparent:= true;
WordWrap:= true;
Font.Name:= 'Arial';
Font.Size:= 8;
Font.Color:= clwhite;
Font.Style := [fsBold];
Alignment := taCenter;
Parent:= WizardForm;
Caption:= cm('Welcome');
end;
with WizardForm.DirEdit do begin
Parent:= WizardForm;
Left:= ScaleX(100);
Top:= ScaleY(250);
Color:= clblack;
Font.Name:= 'Arial';
Font.Size:= 9;
Font.Color:= clwhite;
Width:= ScaleX(324);
Height:= ScaleY(18);
end;
with WizardForm.GroupEdit do begin
Parent:= WizardForm;
Left:= ScaleX(100);
Top:= ScaleY(250);
Color:= clblack;
Font.Name:= 'Arial';
Font.Size:= 9;
Font.Color:= clwhite;
Width:= ScaleX(324);
Height:= ScaleY(18);
end;
Selectlbl1:=TLabel.Create(WizardForm);
with Selectlbl1 do
begin
Left:= ScaleX(100);
Top:= ScaleY(200);
Width:= ScaleX(450);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Parent:= WizardForm;
Caption:= cm('dir1');
end;
Selectlbl2:=TLabel.Create(WizardForm);
with Selectlbl2 do
begin
Left:= ScaleX(100);
Top:= ScaleY(216);
Width:= ScaleX(450);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Parent:= WizardForm;
Caption:= cm('dir2');
end;
//with WizardForm.DirBrowseButton do begin
// Parent:= WizardForm;
// Left:= ScaleX(720);
// Top:= ScaleY(200);
// Font.Name:= 'Arial';
// Font.Size:= 9;
// Font.Color:= $aeacac;
//end;
//with WizardForm.GroupBrowseButton do begin
// Parent:= WizardForm;
// Left:= ScaleX(720);
// Top:= ScaleY(200);
// Font.Name:= 'Arial';
// Font.Size:= 9;
// Font.Color:= $aeacac;
//end;
mb1:=TLabel.Create(WizardForm);
with mb1 do
begin
Left:= ScaleX(100);
Top:= ScaleY(278);
Width:= ScaleX(450);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Parent:= WizardForm;
end;
mb2:=TLabel.Create(WizardForm);
with mb2 do
begin
Left:= ScaleX(100);
Top:= ScaleY(295);
Width:= ScaleX(450);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Parent:= WizardForm;
end;
WizardForm.DirEdit.OnChange:= @GetFreeSpaceCaption;
NoIconsCheck:= TNewCheckbox.Create(WizardForm);
with NoIconsCheck do
begin
Left:= ScaleX(100);
Top:= ScaleY(280);
Width:= ScaleX(13);
Height:= ScaleY(13);
Parent:= WizardForm;
OnClick:= @NoIconsCheckClick;
end;
ExtractTemporaryFile('1.bmp');
with WizardForm.ComponentsList do begin
LoadBGBmpFromFile(ExpandConstant('{tmp}\1.bmp'), Left+100, Top+150);
Parent:= WizardForm;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Font.Color:= clwhite;
left:= ScaleX(100);
BorderStyle:= bsNone;
Top:= ScaleY(200);
Height:= Height - 50;
end;
DeleteFile(ExpandConstant('{tmp}\1.bmp'));
islbl1:=TLabel.Create(WizardForm);
with islbl1 do
begin
Left:= ScaleX(100);
Top:= ScaleY(255);
Width:= ScaleX(450);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Parent:= WizardForm;
Caption:= cm('Extracted');
end;
islbl2:=TLabel.Create(WizardForm);
with islbl2 do
begin
Left:= ScaleX(100);
Top:= ScaleY(270);
Width:= ScaleX(450);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Parent:= WizardForm;
end;
NoIconsLabel:=TLabel.Create(WizardForm);
with NoIconsLabel do
begin
Left:= ScaleX(120);
Top:= ScaleY(280);
Width:= ScaleX(450);
Height:= ScaleY(200);
AutoSize:= false;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Parent:= WizardForm;
Caption:= cm('nic');
OnClick:= @NoIconsLabelClick;
end;
end;
//************************************************ [Конец - Создание лебелов] ***************************************************//
function IniStr(Input: String): String;
begin
Result := InputPage.Values[0];
end;
procedure createInPage();
begin
InputPage := CreateInputQueryPage(wpSelectDir, #0, #0, #0);
InputPage.Add(#0, False);
with InputPage do
begin
Edits[0].Parent:= WizardForm;
Edits[0].SetBounds(ScaleX(100), ScaleX(250), ScaleX(324), ScaleY(18));
Edits[0].Color:= clblack;
Edits[0].Font.Name:= 'Arial';
Edits[0].Font.Size:= 9;
Edits[0].Font.Color:= clwhite;
CaptionLabel:=TLabel.Create(WizardForm);
with CaptionLabel do
begin
Parent:= WizardForm;
SetBounds(ScaleX(100), ScaleX(200), ScaleX(324), ScaleY(26));
AutoSize:= false;
WordWrap := True;
Font.Name:= 'Arial';
Font.Size:= 8
Font.Style := [fsBold];
Transparent:= true;
Font.Color:= clwhite;
Caption:= 'Введите желаемый ник в игре.'
end;
end;
end;
procedure InitializeWizard;
begin
s:= WizardForm.Caption;
Enabled:= true;
CreateLabel;
CreateWizardImg;
ButtonsTextures;
createInPage();
end;
procedure CurPageChanged(CurPageID: Integer);
begin
SetStateNewButtons;
Welcomelbl1.Hide;
WizardForm.DirEdit.Hide;
WizardForm.GroupEdit.Hide;
Selectlbl1.Hide;
Selectlbl2.Hide;
BtnSetVisibility(hDirBrowseBtn, false);
BtnSetVisibility(hGroupBrowseBtn, false);
mb1.Hide;
mb2.Hide;
NoIconsCheck.Hide;
NoIconsLabel.Hide;
WizardForm.ComponentsList.Hide;
islbl1.Hide;
InputPage.Edits[0].Hide;
CaptionLabel.Hide;
if CurPageID = wpWelcome then
begin
Welcomelbl1.Show;
ImgSetVisibility(form, true);
ImgSetVisibility(form1, false);
end;
if CurPageID = wpSelectDir then
begin
GetFreeSpaceCaption(nil);
Selectlbl2.Caption:= cm('Dir2');
WizardForm.DirEdit.Show;
Selectlbl1.Show;
Selectlbl1.Caption:= cm('Dir1');
Selectlbl2.Show;
BtnSetVisibility(hDirBrowseBtn, true);
ImgSetVisibility(form1, true);
ImgSetVisibility(form, false);
mb1.Show;
mb2.Show;
end;
if CurPageID = InputPage.ID then
begin
InputPage.Edits[0].Show;
CaptionLabel.Show;
end;
if CurPageID = wpSelectComponents then WizardForm.ComponentsList.Show;
if CurPageID = wpSelectProgramGroup then
begin
Selectlbl1.Caption:= cm('Group1');
Selectlbl1.Show;
Selectlbl2.Show;
Selectlbl2.Caption:= cm('Dir2');
WizardForm.GroupEdit.Show;
BtnSetVisibility(hGroupBrowseBtn, true);
NoIconsCheck.Show;
NoIconsLabel.Show;
WizardForm.NextButton.Caption:= 'Установить';
end;
if CurPageID = wpSelectTasks then
begin
end;
if CurPageID = wpReady then
begin
ImgSetVisibility(form1, true);
end;
if CurPageID = wpInstalling then
begin
ImgSetVisibility(form, true);
ImgSetVisibility(form1, false);
islbl1.Show;
end;
if CurPageID = wpFinished then
begin
ImgSetVisibility(form, true);
islbl2.Hide;
Welcomelbl1.Show;
Welcomelbl1.Caption:= cm('Fin');
Welcomelbl1.Top:= Welcomelbl1.Top+ScaleY(5);
end;
if (CurPageID = wpFinished) and ISDoneError then
begin
Welcomelbl1.Show;
Welcomelbl1.Font.Color:= clred;
Welcomelbl1.Caption:= cm('FinError');
end;
ImgApplyChanges(WizardForm.Handle);
end;
procedure CurStepChanged(CurStep: TSetupStep);
var Comps1,Comps2,Comps3, TmpValue:cardinal;
FindHandle1,ColFiles1,CurIndex1,tmp:integer;
ExecError:boolean;
InFilePath,OutFilePath,OutFileName:PAnsiChar;
begin
if CurStep = ssInstall then begin //Если необходимо, можно поменять на ssPostInstall
WizardForm.ProgressGauge.Hide;
WizardForm.CancelButton.Hide;
ISDonePB:= ImgPBCreate(WizardForm.Handle, ExpandConstant('pb2.png'),ExpandConstant('pb1.png'), ScaleX(100), ScaleY(290), ScaleX(420), ScaleY(19));
WizardForm.StatusLabel.Caption:=ExpandConstant('{cm:Extracted}');
ISDoneCancel:=0;
// Распаковка всех необходимых файлов в папку {tmp}.
ExtractTemporaryFile('unarc.dll');
#ifdef PrecompInside
ExtractTemporaryFile('CLS-precomp.dll');
ExtractTemporaryFile('packjpg_dll.dll');
ExtractTemporaryFile('packjpg_dll1.dll');
ExtractTemporaryFile('precomp.exe');
ExtractTemporaryFile('zlib1.dll');
#endif
#ifdef SrepInside
ExtractTemporaryFile('CLS-srep.dll');
#endif
#ifdef MSCInside
ExtractTemporaryFile('CLS-MSC.dll');
#endif
#ifdef facompress
ExtractTemporaryFile('facompress.dll'); //ускоряет распаковку .arc архивов.
#endif
#ifdef records
ExtractTemporaryFile('records.inf');
#endif
#ifdef precomp
#if precomp == "0.38"
ExtractTemporaryFile('precomp038.exe');
#else
#if precomp == "0.4"
ExtractTemporaryFile('precomp040.exe');
#else
#if precomp == "0.41"
ExtractTemporaryFile('precomp041.exe');
#else
#if precomp == "0.42"
ExtractTemporaryFile('precomp042.exe');
#else
ExtractTemporaryFile('precomp038.exe');
ExtractTemporaryFile('precomp040.exe');
ExtractTemporaryFile('precomp041.exe');
ExtractTemporaryFile('precomp042.exe');
#endif
#endif
#endif
#endif
#endif
#ifdef unrar
ExtractTemporaryFile('Unrar.dll');
#endif
#ifdef XDelta
ExtractTemporaryFile('XDelta3.dll');
#endif
#ifdef PackZIP
ExtractTemporaryFile('7z.dll');
ExtractTemporaryFile('PackZIP.exe');
#endif
// Подготавливаем переменную, содержащую всю информацию о выделенных компонентах для ISDone.dll
// максимум 96 компонентов.
Comps1:=0; Comps2:=0; Comps3:=0;
#ifdef Components
TmpValue:=1;
if IsComponentSelected('text\rus') then Comps1:=Comps1+TmpValue; //компонент 1
TmpValue:=TmpValue*2;
if IsComponentSelected('text\eng') then Comps1:=Comps1+TmpValue; //компонент 2
TmpValue:=TmpValue*2;
if IsComponentSelected('voice\rus') then Comps1:=Comps1+TmpValue; //компонент 3
TmpValue:=TmpValue*2;
if IsComponentSelected('voice\eng') then Comps1:=Comps1+TmpValue; //компонент 4
// .....
// см. справку
#endif
#ifdef precomp
PCFVer:={#precomp};
#else
PCFVer:=0;
#endif
ISDoneError:=true;
if ISDoneInit(ExpandConstant('{src}\records.inf'), $F777, Comps1,Comps2,Comps3, MainForm.Handle, 0, @ProgressCallback) then begin
repeat
if not SrepInit('',512,0) then break;
if not PrecompInit('',128,PCFVer) then break;
if not FileSearchInit(true) then break;
if not ISArcExtract ( 0, 0, ExpandConstant('{src}\*.arc'), ExpandConstant('{app}'), '', false, '', '', ExpandConstant('{app}'), notPCFonFLY {PCFonFLY}) then break;
// далее находятся закомментированые примеры различных функций распаковки (чтобы каждый раз не лазить в справку за примерами)
(*
if not ISArcExtract ( 0, 0, ExpandConstant('{src}\arc.arc'), ExpandConstant('{app}\'), '', false, '', ExpandConstant('{tmp}\arc.ini'), ExpandConstant('{app}\'), notPCFonFLY{PCFonFLY}) then break;
if not IS7ZipExtract ( 0, 0, ExpandConstant('{src}\CODMW2.7z'), ExpandConstant('{app}\data1'), false, '') then break;
if not ISRarExtract ( 0, 0, ExpandConstant('{src}\data_*.rar'), ExpandConstant('{app}'), false, '') then break;
if not ISSRepExtract ( 0, 0, ExpandConstant('{app}\data1024_1024.srep'),ExpandConstant('{app}\data1024.arc'), true) then break;
if not ISPrecompExtract( 0, 0, ExpandConstant('{app}\data.pcf'), ExpandConstant('{app}\data.7z'), true) then break;
if not ISxDeltaExtract ( 0, 0, 0, 640, ExpandConstant('{app}\in.pcf'), ExpandConstant('{app}\*.diff'), ExpandConstant('{app}\out.dat'), false, false) then break;
if not ISPackZIP ( 0, 0, ExpandConstant('{app}\1a1\*'), ExpandConstant('{app}\1a1.pak'), 2, false ) then break;
if not ISExec ( 0, 0, 0, ExpandConstant('{tmp}\Arc.exe'), ExpandConstant('x -o+ "{src}\001.arc" "{app}\"'), ExpandConstant('{tmp}'), '...',false) then break;
if not ShowChangeDiskWindow ('Пожалуйста, вставьте второй диск и дождитесь его инициализации.', ExpandConstant('{src}'),'CODMW_2.arc') then break;
// распаковка группы файлов посредством внешнего приложения
FindHandle1:=ISFindFiles(0,ExpandConstant('{app}\*.ogg'),ColFiles1);
ExecError:=false;
while not ExecError and ISPickFilename(FindHandle1,ExpandConstant('{app}\'),CurIndex1,true) do begin
InFilePath:=ISGetName(0);
OutFilePath:=ISGetName(1);
OutFileName:=ISGetName(2);
ExecError:=not ISExec(0, 0, 0, ExpandConstant('{tmp}\oggdec.exe'), '"'+InFilePath+'" -w "'+OutFilePath+'"',ExpandConstant('{tmp}'),OutFileName,false);
end;
ISFindFree(FindHandle1);
if ExecError then break;
*)
ISDoneError:=false;
until true;
ImgPBDelete(ISDonePB);
islbl2.Hide;
islbl1.Caption:= SetupMessage(msgStatusRunProgram);
ISDoneStop;
end;
WizardForm.CancelButton.Visible:=true;
WizardForm.CancelButton.Enabled:=false;
end;
if (CurStep=ssPostInstall) and ISDoneError then begin
Exec2(ExpandConstant('{uninstallexe}'), '/VERYSILENT', false);
end;
end;
procedure DeinitializeSetup;
begin
if Enabled then gdipShutdown;
WizardForm.Free;
end;
novahudonoser
16-01-2014, 23:05
Ладно
покуда нет решения как корректно завершить процесс на этапе установки спрошу ещё вот что:
есть небольшой код который находит запущенный процесс
интересует следующее, как его допилить чтобы установщик отключал кнопку [Далее] дабы пользователь выполнил требование (закрыл требуемый процесс)
function IsProcessRunning(FileName: String): Boolean;
var
objSWbemLocator, objSWbemServices: Variant;
begin
try
objSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
except
ShowExceptionMessage;
Exit;
end;
objSWbemServices := objSWbemLocator.ConnectServer();
objSWbemServices.Security_.ImpersonationLevel := 3;
Result := (objSWbemServices.ExecQuery('SELECT * FROM Win32_Process WHERE Name="' + FileName + '"').Count > 0);
end;
procedure InitializeWizard();
begin
if IsProcessRunning('calc.exe') then
// Программа запущена, какие варианты у установщика
// прервать установку и закрыться либо
// ожидать когда пользователь самостоятельно завешит работу программы и продолжит установку
else
// Программа не запущено можно продолжить установку
end;
я уже не уверен что это вообще заработает
может ктонить запустить у себя проверить что не так с этим кодом? »
С этим кодом все в порядке. Просто вы компилируете на стандартной версии Inno. Установите расширенную версию от китайских собратьев, она есть в шапке соседней темы http://forum.oszone.net/showthread.php?p=1201499# , и проблема исчерпает себя.
чтобы установщик отключал кнопку [Далее] дабы пользователь выполнил требование (закрыл требуемый процесс) »
#ifndef IS_ENHANCED
#error Enhanced edition of Inno Setup (restools) is required to compile this script
#endif
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=.
[Code]
const
TIMER_ID = 01;
type
TFNTimerProc = Longint;
function SetTimer(hWnd: HWND; nIDEvent, uElapse: UINT; lpTimerFunc: TFNTimerProc): UINT; external 'SetTimer@user32.dll stdcall';
function KillTimer(hWnd: HWND; uIDEvent: UINT): BOOL; external 'KillTimer@user32.dll stdcall';
function IsProcessRunning(FileName: String): Boolean;
var
objSWbemLocator, objSWbemServices: Variant;
begin
try
objSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
except
ShowExceptionMessage;
Exit;
end;
objSWbemServices := objSWbemLocator.ConnectServer();
objSWbemServices.Security_.ImpersonationLevel := 3;
Result := (objSWbemServices.ExecQuery('SELECT * FROM Win32_Process WHERE Name="' + FileName + '"').Count > 0);
end;
procedure TimerProc(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD);
begin
WizardForm.NextButton.Enabled := not IsProcessRunning('calc.exe');
end;
procedure CurPageChanged(CurPageID: Integer);
begin
case CurPageID of
wpWelcome: SetTimer(WizardForm.Handle, TIMER_ID, 30, CallbackAddr('TimerProc'));
wpInstalling: KillTimer(WizardForm.Handle, TIMER_ID);
end;
end;
procedure DeinitializeSetup();
begin
KillTimer(WizardForm.Handle, TIMER_ID);
end;
----------------------------------------------------------------------------------------
Только правильней будет проверять все это дело на этапе инициализации, с выводом MsgBox с соответствующим сообщением, если будет обнаружен запущенный процесс приложения, дабы не ввергнуть пользователя в недоумение, при виде неактивной кнопки "Далее".
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=.
[Code]
function IsProcessRunning(FileName: String): Boolean;
var
objSWbemLocator, objSWbemServices: Variant;
begin
try
objSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
except
ShowExceptionMessage;
Exit;
end;
objSWbemServices := objSWbemLocator.ConnectServer();
objSWbemServices.Security_.ImpersonationLevel := 3;
Result := (objSWbemServices.ExecQuery('SELECT * FROM Win32_Process WHERE Name="' + FileName + '"').Count > 0);
end;
function InitializeSetup(): Boolean;
begin
Result := not IsProcessRunning('calc.exe');
if not Result then MsgBox('Обновляемое приложение запущено. Завершите процесс приложения и повторите попытку.', mbError, MB_OK);
end;
----------------------------------------------------------------------------------------
И пример от El Sanchez (http://forum.oszone.net/member.php?userid=132675), адаптированный под ваши нужды(обнаружение запущенного процесса и его закрытие по запросу).
#ifndef IS_ENHANCED
#error Enhanced edition of Inno Setup (restools) is required to compile this script
#endif
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=.
[Code]
#define A = (Defined UNICODE) ? "W" : "A"
const
TH32CS_SNAPPROCESS = $2;
INVALID_HANDLE_VALUE = -1;
PROCESS_TERMINATE = $1;
PROCESS_CREATE_THREAD = $2;
PROCESS_VM_OPERATION = $8;
PROCESS_VM_READ = $10;
PROCESS_VM_WRITE = $20;
PROCESS_QUERY_INFORMATION = $400;
SYNCHRONIZE = $100000;
MEM_COMMIT = $1000;
MEM_RESERVE = $2000;
PAGE_EXECUTE_READWRITE = $40;
TOKEN_QUERY = $8;
TOKEN_ADJUST_PRIVILEGES = $20;
SE_PRIVILEGE_ENABLED = $2;
MAX_PATH = 260;
TA_FAILED = 0;
TA_SUCCESS_CLEAN = 1;
TA_SUCCESS_KILL = 2;
WM_CLOSE = $10;
WAIT_OBJECT_0 = $0;
WAIT_TIMEOUT = $102;
type
TPROCESSENTRY32 = record
dwSize, cntUsage, th32ProcessID: DWORD;
th32DefaultHeapID: Longint;
th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array [0..259] of Char;
end;
LUID = record
LowPart: DWORD;
HighPart: Longint;
end;
LUID_AND_ATTRIBUTES = record
Luid: LUID;
Attributes: DWORD;
end;
TOKEN_PRIVILEGES = record
PrivilegeCount: DWORD;
Privileges: array [0..0] of LUID_AND_ATTRIBUTES;
end;
function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
#ifdef UNICODE
function Process32First(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32First{#A}@kernel32.dll stdcall';
function Process32Next(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32Next{#A}@kernel32.dll stdcall';
#else
function Process32First(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32First@kernel32.dll stdcall';
function Process32Next(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32Next@kernel32.dll stdcall';
#endif
function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; external 'OpenProcess@kernel32.dll stdcall';
function OpenProcessToken(ProcessHandle: THandle; DesiredAccess: DWORD; var TokenHandle: THandle): BOOL; external 'OpenProcessToken@advapi32.dll stdcall';
function GetCurrentProcess(): THandle; external 'GetCurrentProcess@kernel32.dll stdcall';
function LookupPrivilegeValue(lpSystemName, lpName: String; var lpLuid: LUID): BOOL; external 'LookupPrivilegeValue{#A}@advapi32.dll stdcall';
function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL; NewState: TOKEN_PRIVILEGES; BufferLength: DWORD; var PreviousState: TOKEN_PRIVILEGES; var ReturnLength: Longint): BOOL; external 'AdjustTokenPrivileges@advapi32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';
function GetProcessImageFileName(hProcess: THandle; var lpImageFileName: Char; nSize: DWORD): DWORD; external 'GetProcessImageFileName{#A}@psapi.dll stdcall';
function QueryDosDevice(lpDeviceName: String; var lpTargetPath: Char; ucchMax: DWORD): DWORD; external 'QueryDosDevice{#A}@kernel32.dll stdcall';
function EnumWindows(lpEnumFunc, lParam: Longint): BOOL; external 'EnumWindows@user32.dll stdcall';
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; external 'WaitForSingleObject@kernel32.dll stdcall';
function GetProcAddress(hModule: THandle; lpProcName: String): Longint; external 'GetProcAddress@kernel32.dll stdcall';
function GetModuleHandle(lpModuleName: String): THandle; external 'GetModuleHandle{#A}@kernel32.dll stdcall';
function VirtualAllocEx(hProcess: THandle; lpAddress, dwSize: Longint; flAllocationType, flProtect: DWORD): Longint; external 'VirtualAllocEx@kernel32.dll stdcall';
function WriteProcessMemory(hProcess: THandle; lpBaseAddress, lpBuffer, nSize: Longint; var lpNumberOfBytesWritten: Longint): BOOL; external 'WriteProcessMemory@kernel32.dll stdcall';
function CreateRemoteThread(hProcess: THandle; lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; external 'CreateRemoteThread@kernel32.dll stdcall';
function TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL; external 'TerminateProcess@kernel32.dll stdcall';
function GetWindowThreadProcessId(hWnd: HWND; var lpdwProcessId: DWORD): DWORD; external 'GetWindowThreadProcessId@user32.dll stdcall';
function GetLogicalDrives: DWord; external 'GetLogicalDrives@kernel32.dll stdcall';
function CharArrayToString(aChar: array of Char): String;
begin
Result := '';
while aChar[Length(Result)] <> #0 do Insert(aChar[Length(Result)], Result, Length(Result)+1);
end;
function EnumWindowsProc(hwnd: HWND; lParam: Longint): BOOL;
var
dwID: DWORD;
begin
GetWindowThreadProcessId(hwnd, dwID);
if dwID = lParam then PostMessage(hwnd, WM_CLOSE, 0, 0);
Result := True;
end;
function TerminateApp(const szProcess: String; dwTimeout: DWORD): DWORD;
var
hProcessSnap, hProc, hToken, hThread, lpProcName: THandle;
pe32: TPROCESSENTRY32;
aBuf: array [0..259] of Char;
szFileName, szDeviceName: String;
tkp: TOKEN_PRIVILEGES;
SeDebugNameValue: LUID;
i, lpMemory, ret: Longint;
lpThreadId, dwDrives: DWORD;
begin
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
try
pe32.dwSize := SizeOf(pe32);
if not Process32First(hProcessSnap, pe32) then Exit;
while Process32Next(hProcessSnap, pe32) do
begin
if CompareText(CharArrayToString(pe32.szExeFile), ExtractFileName(szProcess)) <> 0 then Continue;
hProc := OpenProcess(PROCESS_TERMINATE or PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION or SYNCHRONIZE, False, pe32.th32ProcessID);
if hProc = TA_FAILED then
begin
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then Exit;
if not LookupPrivilegeValue('', 'SeDebugPrivilege', SeDebugNameValue) then Exit;
try
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := SeDebugNameValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
if not AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ret) then Exit;
hProc := OpenProcess(PROCESS_TERMINATE or PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION or SYNCHRONIZE, False, pe32.th32ProcessID);
if hProc = TA_FAILED then Exit;
finally
tkp.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ret);
CloseHandle(hToken);
end;
end;
if CompareText(szProcess, ExtractFileName(szProcess)) <> 0 then
begin
GetProcessImageFileName(hProc, aBuf[0], SizeOf(aBuf));
szFileName := CharArrayToString(aBuf);
dwDrives := GetLogicalDrives();
for i := 2 to 25 do if dwDrives and (1 shl i) <> 0 then
begin
QueryDosDevice(Format('%s:', [Chr(Ord('A') + i)]), aBuf[0], SizeOf(aBuf));
szDeviceName := CharArrayToString(aBuf);
if Pos(szDeviceName, szFileName) = 0 then Continue;
StringChangeEx(szFileName, szDeviceName, Format('%s:', [Chr(Ord('A') + i)]), True);
if CompareText(szProcess, szFileName) = 0 then Break;
end;
if CompareText(szProcess, szFileName) <> 0 then
begin
CloseHandle(hProc);
Continue;
end;
end;
try
EnumWindows(CallbackAddr('EnumWindowsProc'), pe32.th32ProcessID);
case WaitForSingleObject(hProc, dwTimeout) of
WAIT_OBJECT_0: Result := TA_SUCCESS_CLEAN;
WAIT_TIMEOUT: try
lpProcName := GetProcAddress(GetModuleHandle('kernel32.dll'), 'ExitProcess');
if lpProcName = 0 then Exit;
lpMemory := VirtualAllocEx(hProc, 0, SizeOf(lpProcName), MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if not WriteProcessMemory(hProc, lpMemory, lpProcName, SizeOf(lpProcName), ret) then Exit;
hThread := CreateRemoteThread(hProc, 0, 0, lpMemory, 0, 0, lpThreadId);
if hThread > 0 then
case WaitForSingleObject(hThread, dwTimeout) of
WAIT_OBJECT_0: Result := TA_SUCCESS_CLEAN;
WAIT_TIMEOUT: if TerminateProcess(hProc, 0) then Result := TA_SUCCESS_KILL;
end;
finally
CloseHandle(hThread);
end;
end;
finally
CloseHandle(hProc);
if CompareText(szProcess, ExtractFileName(szProcess)) <> 0 then Exit;
end;
end;
finally
CloseHandle(hProcessSnap);
end;
end;
function IsProcessRunning(FileName: String): Boolean;
var
objSWbemLocator, objSWbemServices: Variant;
begin
try
objSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
except
ShowExceptionMessage;
Exit;
end;
objSWbemServices := objSWbemLocator.ConnectServer();
objSWbemServices.Security_.ImpersonationLevel := 3;
Result := (objSWbemServices.ExecQuery('SELECT * FROM Win32_Process WHERE Name="' + FileName + '"').Count > 0);
end;
function InitializeSetup(): Boolean;
var
pName: String;
begin
pName := 'calc.exe';
Result := not IsProcessRunning(pName);
if not Result then
case MsgBox('Обновляемое приложение запущено. Завершить работу приложения в принудительном режиме?' + #13#13 + '"Да" - завершение работы приложения и запуск установки.' + #13#10 + '"Нет" - выход из программы установки.', mbError, MB_YESNO) of
IDYES:
begin
TerminateApp(pName, 5000);
Result := True;
end;
end;
end;
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.