Войти

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


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

saurn
27-01-2014, 18:39
innot20,
[Setup]
AppName=My Program
AppVerName=My Program v 1.5
DefaultDirName={pf}\My Program
OutputDir=.


[code]
const
TH32CS_SNAPPROCESS = $2;
INVALID_HANDLE_VALUE = -1;
TIMER_ID = 01;

type
TPROCESSENTRY32 = record
dwSize, cntUsage, th32ProcessID: DWORD;
th32DefaultHeapID: Longint;
th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array [0..259] of char;
end;

TFNTimerProc = Longint;

function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
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';
function CloseHandle(hObject: THandle): Boolean; external 'CloseHandle@kernel32.dll stdcall';
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';


var
msgPage: TOutputMsgWizardPage;


function IsProcessRunning(FileName: String): Boolean;
var
hProcessSnap: THandle;
pe32: TPROCESSENTRY32;
szExeFile: String;
begin
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
pe32.dwSize := sizeof(pe32);
if not Process32First(hProcessSnap, pe32) then Exit;
while not Result and Process32Next(hProcessSnap, pe32) do
begin
szExeFile := '';
while not (pe32.szExeFile[Length(szExeFile)] = #0) do szExeFile := szExeFile + pe32.szExeFile[Length(szExeFile)];
Result := LowerCase(FileName) = LowerCase(szExeFile);
end;
CloseHandle(hProcessSnap);
end;


procedure TimerProc(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD);
begin
WizardForm.NextButton.Enabled := not IsProcessRunning('WorldOfTanks.exe');
end;


procedure InitializeWizard();
begin
msgPage := CreateOutputMsgPage(wpSelectComponents, 'Заголовок', 'Подзаголовок', 'Сообщение');
end;


function ShouldSkipPage(PageID: Integer): Boolean;
begin
case PageFromID(PageID) of
msgPage: Result := not IsProcessRunning('WorldOfTanks.exe');
end;
end;


procedure CurPageChanged(CurPageID: Integer);
begin
KillTimer(WizardForm.Handle, TIMER_ID);

case PageFromID(CurPageID) of
msgPage: if IsProcessRunning('WorldOfTanks.exe') then SetTimer(WizardForm.Handle, TIMER_ID, 30, CallbackAddr('TimerProc'));
end;
end;


procedure DeinitializeSetup();
begin
KillTimer(WizardForm.Handle, TIMER_ID);
end;


И еще:
[Setup]
AppName=My Program
AppVerName=My Program v 1.5
DefaultDirName={pf}\My Program
OutputDir=.


[code]
const
TH32CS_SNAPPROCESS = $2;
INVALID_HANDLE_VALUE = -1;

type
TPROCESSENTRY32 = record
dwSize, cntUsage, th32ProcessID: DWORD;
th32DefaultHeapID: Longint;
th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array [0..259] of char;
end;


function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
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';
function CloseHandle(hObject: THandle): Boolean; external 'CloseHandle@kernel32.dll stdcall';


var
msgPage: TOutputMsgWizardPage;


function IsProcessRunning(FileName: String): Boolean;
var
hProcessSnap: THandle;
pe32: TPROCESSENTRY32;
szExeFile: String;
begin
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
pe32.dwSize := sizeof(pe32);
if not Process32First(hProcessSnap, pe32) then Exit;
while not Result and Process32Next(hProcessSnap, pe32) do
begin
szExeFile := '';
while not (pe32.szExeFile[Length(szExeFile)] = #0) do szExeFile := szExeFile + pe32.szExeFile[Length(szExeFile)];
Result := LowerCase(FileName) = LowerCase(szExeFile);
end;
CloseHandle(hProcessSnap);
end;


function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;

case PageFromID(CurPageID) of
msgPage:
begin
if not IsProcessRunning('WorldOfTanks.exe') then Result := True
else begin
MsgBox('Программа все еще запущена', mbError, MB_OK);
Result := False;
end;
end;
end;
end;


procedure InitializeWizard();
begin
msgPage := CreateOutputMsgPage(wpSelectComponents, 'Заголовок', 'Подзаголовок', 'Сообщение');
end;


function ShouldSkipPage(PageID: Integer): Boolean;
begin
case PageFromID(PageID) of
msgPage: Result := not IsProcessRunning('WorldOfTanks.exe');
end;
end;

innot20
27-01-2014, 19:05
saurn, запустил танки, запустил установщик и установил все моды без проблем, то что включен процесс сообщений не выдало

Nordek
27-01-2014, 19:06
saurn, procedure TimerProc(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD);
begin
WizardForm.NextButton.Enabled := not IsProcessRunning('calc.exe');
end;


procedure TimerProc(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD);
begin
WizardForm.NextButton.Enabled := not IsProcessRunning(''WorldOfTanks.exe');
end;
#define KillExe "WorldOfTanks.exe"

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


[code]
const
TH32CS_SNAPPROCESS = $2;
INVALID_HANDLE_VALUE = -1;
TIMER_ID = 01;

type
TPROCESSENTRY32 = record
dwSize, cntUsage, th32ProcessID: DWORD;
th32DefaultHeapID: Longint;
th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array [0..259] of char;
end;

TFNTimerProc = Longint;

function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
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';
function CloseHandle(hObject: THandle): Boolean; external 'CloseHandle@kernel32.dll stdcall';
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';


var
msgPage: TOutputMsgWizardPage;


function IsProcessRunning(FileName: String): Boolean;
var
hProcessSnap: THandle;
pe32: TPROCESSENTRY32;
szExeFile: String;
begin
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
pe32.dwSize := sizeof(pe32);
if not Process32First(hProcessSnap, pe32) then Exit;
while not Result and Process32Next(hProcessSnap, pe32) do
begin
szExeFile := '';
while not (pe32.szExeFile[Length(szExeFile)] = #0) do szExeFile := szExeFile + pe32.szExeFile[Length(szExeFile)];
Result := LowerCase(FileName) = LowerCase(szExeFile);
end;
CloseHandle(hProcessSnap);
end;


procedure TimerProc(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD);
begin
WizardForm.NextButton.Enabled := not IsProcessRunning('{#KillExe}');
end;


procedure InitializeWizard();
begin
msgPage := CreateOutputMsgPage(wpSelectComponents, 'Заголовок', 'Подзаголовок', 'Сообщение');
end;


function ShouldSkipPage(PageID: Integer): Boolean;
begin
case PageFromID(PageID) of
msgPage: Result := not IsProcessRunning('{#KillExe}');
end;
end;


procedure CurPageChanged(CurPageID: Integer);
begin
KillTimer(WizardForm.Handle, TIMER_ID);

case PageFromID(CurPageID) of
msgPage: if IsProcessRunning('{#KillExe}') then SetTimer(WizardForm.Handle, TIMER_ID, 30, CallbackAddr('TimerProc'));
end;
end;


procedure DeinitializeSetup();
begin
KillTimer(WizardForm.Handle, TIMER_ID);
end;

diman_21Ru
27-01-2014, 19:08
saurn , огромнейшее тебе спасибо :)

Nordek
27-01-2014, 19:16
то что включен процесс сообщений не выдало »Потому что на юникодной версии Inno компилил, у меня на ANSI всё нормально работает.

saurn
27-01-2014, 19:21
запустил танки, запустил установщик и установил все моды без проблем, то что включен процесс сообщений не выдало »
Тестировал на процессе калькулятора и забыл изменить в одном месте. Поправил. А так, все работает.

innot20
27-01-2014, 20:07
Спасибо всем за помощь

Nordek
27-01-2014, 20:57
А так, все работает. » А я ещё раз повторю, что примеры (http://forum.oszone.net/post-2297406-2001.html) на юникодной версии не будут работать.

saurn
27-01-2014, 21:00
на юникодной версии не будут работать »
Юникодовой никогда не пользовался. Про нее и слова не было. На ANSI все работает.

innot20
27-01-2014, 21:23
помогите пожалуйста ещё сделать проверку на версию игры
считать версию игры можно 3 способами
1. файл version.xml
его содержимое:
<version.xml>
<appname> #menu:login/version </appname>
<version> v.0.8.11 Common Test #578</version> // цифра 578 может меняться у другого пользователя
<showLicense> 0 </showLicense>
<ingameHelpVersion> 1 </ingameHelpVersion>
<meta>
<client>368825</client>
<overrides>368619</overrides>
<localization>368469 RU</localization>
</meta>
</version.xml>


2. у файла WorldOfTanks.exe в свойствах > подробно
есть версия файла
0.8.11.0

3. файл paths.xml
содержимое первых 3 строчек
<root>
<Paths>
<Path>./res_mods/0.8.11 Common Test</Path>

Gnom_aka_Lexander
27-01-2014, 21:30
innot20, по версии файла встроенными функциями:
function GetVersionNumbers(const Filename: String; var VersionMS, VersionLS: Cardinal): Boolean;
VersionMS и VersionLS типа Cardinal объявить заранее, в них будут номера версии.
function GetVersionNumbersString(const Filename: String; var Version: String): Boolean;
тут номер версии вернется строкой.
Filename - полный путь к файлу, чью версию нужно узнать. справка - :up сила.

nik1967
27-01-2014, 22:09
innot20, http://forum.oszone.net/post-2236471.html#post2236471

Nordek
28-01-2014, 05:55
innot20, Если же в случае отсутствия файла допустить установку, то так:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application
OutputDir=.
DirExistsWarning=no

[Code]
function FileVersion(const FilePath: String): String;
var
oFS: Variant;
begin
oFS:= CreateOleObject('Scripting.FileSystemObject');
try
Result:= oFS.GetFileVersion(FilePath);
except
end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result:= true;

case CurPageID of
wpSelectDir:
begin
if FileExists(ExpandConstant('{app}')+'\GameName.exe') then begin
if FileVersion(ExpandConstant('{app}')+'\GameName.exe') < '2.0.0.1' then begin
MsgBoxEx(WizardForm.Handle, 'На данную версию невозможно продолжить установку!', 'Не актуальная версия файла', MB_OK or MB_ICONWARNING, 0, 0);
Result:= false;
end;
end;
end;
end;
end;

по версии файла встроенными функциями »Ну ты молодец, типа он понял что ты сказал.
Справка-то сила, но в пределах разумного.

Gnom_aka_Lexander
28-01-2014, 10:43
Nordek, ты прям такой умный. Почему тогда не проверить версию файла встроенными средствами? Или только и умеешь, что криво переделывать чужие примеры? Делай тогда уже правильно, раз весь из себя такой великий гуру.
То, что ты как-бы переделал: у тебя на странице выбора папки нет положительного выхода, только отрицательный. делается это так:
function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result:= true;
case CurPageID of
wpSelectDir:
begin
Result:= FileExists(ExpandConstant('{app}\GameName.exe'));
if Result then
Result := FileVersion(ExpandConstant('{app}\GameName.exe')) < '2.0.0.1';
if not Result then
MsgBoxEx(WizardForm.Handle, 'На данную версию невозможно продолжить установку!', 'Не актуальная версия файла', MB_OK or MB_ICONWARNING, 0, 0);
end;
end;
end;
далее на встроенной функции:
function NextButtonClick(CurPageID: Integer): Boolean;
var
Version: String;
begin
Result:= true;
case CurPageID of
wpSelectDir:
begin
Result:= FileExists(ExpandConstant('{app}\GameName.exe'));
if Result then
Result:= GetVersionNumbersString(ExpandConstant('{app}\GameName.exe')), Version);
if Result then
Result := (Version < '2.0.0.1');
if not Result then
MsgBoxEx(WizardForm.Handle, 'На данную версию невозможно продолжить установку!', 'Не актуальная версия файла', MB_OK or MB_ICONWARNING, 0, 0);
end;
end;
end; сложно что-ли набросать пример, если считаешь человека ущербным?
P.S.
Поскольку условий больше одного, то правильным будет оповестить, какое именно условие не дает идти дальше:
function NextButtonClick(CurPageID: Integer): Boolean;
var
Version, StrErr: String;
i : Integer;
begin
Result:= true;
case CurPageID of
wpSelectDir:
begin
i := 0;
if not FileExists(ExpandConstant('{app}\GameName.exe'))then i := 1 else
if not GetVersionNumbersString(ExpandConstant('{app}\GameName.exe'), Version) then i := 2 else
if not (Version < '2.0.0.1') then i := 3;
Result:= i=0;
if not Result then
begin
case i of
1 : StrErr := 'Не обнаружен файл '+ExpandConstant('{app}\GameName.exe');
2 : StrErr := 'Невозможно определить версию файла';
3 : StrErr := 'На данную версию невозможно продолжить установку!';
end;
MsgBox(StrErr, mbError,MB_OK);
end;
end;
end;
end;

Nordek
28-01-2014, 12:11
ты прям такой умный. »В пределах разумного. Я у вас мистер хлеб украл? Чего же тогда когда нужно вы мистер не пример предоставили а пытались своими нравоучениями поучить?
Может всего на один раз нужно сделать инсталлятор - а для этого ничего учить не обязательно как и справки всякие читать.
Если человек всерьёз возьмётся за это дело - тогда да, и справочную информацию почитает и у вас спрашивать ничего не будет.

делается это так: »Можешь когда хочешь - для вытягивания ответа, нет ничего лучше чем манипуляция, даже если при этом придётся специально допустить ошибку.

Gnom_aka_Lexander
28-01-2014, 12:23
Nordek, Знаешь, чем отличается помощь, от настоящей помощи? Сначала была именно помощь. потом - это уже не пример, а полностью готовый для использования код, и это уже не помощь. это уже действие, которое в итоге ведет к последующему зафлуживанию форумов, когда человек видя, что тут ему сделают все, что он хочет, начинает обижаться, когда именно ты ему начнешь отказывать, видя такую наглость. Это было неоднократно и будет не раз. именно поэтому нужно различать помощь и "сделайте за меня все". я не хочу сказать, что именно данный вопрошающий начнет именно так поступать. Я хочу сказать, что нужно заставлять людей думать и читать справки. не бывает неразумных пределов в чтении справки, поскольку там есть абсолютно все. А форумы в идеале нужны для того, что-бы разъяснять непонятные моменты. тут-же вопрос прозвучал - как сделать то-то. при чем простой поиск по справке по слову version моментально дает ответ на этот вопрос. вот если-бы человек спросил "как применить функцию GetVersionNumbers или GetVersionNumbersString", то тогда мой "пример" был-бы именно помощью. А в данной ситуации - это не помощь, а "сделай за меня"

Nordek
28-01-2014, 13:24
Я хочу сказать, что нужно заставлять людей думать и читать справки. »
Gnom_aka_Lexander, Всех людей не переделаешь - с этим трудно не согласиться. Говорить про элитные функции и процедуры и давать советы типа "смотри в сторону GetVersionNumbers" - это как минимум глупо, исходя из того что человек даже не знает что такое функция в программном коде. Забудем на мгновение про литературу - т.к для лентяев это сверхчеловеческих возможностей и справки для них это миф. Ещё раз забудем на мгновение про литературу т.к ответы можно найти и здесь не заглядывая в книгу. Уже со счёта сбился сколько раз указал ссылку на 662 сообщение (http://forum.oszone.net/post-2169372-662.html) и это не единичный случай того, сколько раз здесь давались ответы на одни и те же вопросы. А если никто не ответит, создают одно и тоже сообщение за сообщением. Людям не то что лень что-то читать, но даже найти готовое.

Тем более здесь есть возможность не переходить со страницы на страницу что значительно упрощает поиск:
Inno Setup [все вопросы] часть 1 (http://forum.oszone.net/showthread.php?t=60604&page=all)
Скрипты Inno Setup. Помощь и советы [часть 2] (http://forum.oszone.net/showthread.php?t=148703&page=all)
Скрипты Inno Setup. Помощь и советы [часть 3] (http://forum.oszone.net/showthread.php?t=190621&page=all)
Скрипты Inno Setup. Помощь и советы [часть 4] (http://forum.oszone.net/showthread.php?t=218969&page=all)
Скрипты Inno Setup. Помощь и советы [часть 5] (http://forum.oszone.net/showthread.php?t=244295&page=all)
Скрипты Inno Setup. Помощь и советы [часть 6] (http://forum.oszone.net/showthread.php?t=235078&page=all)

XXXler
28-01-2014, 16:19
Попытка добавления в реестр следующей записи вызывает при установке ошибку 87 в ф-ции RegCreateKeyEx - это баг Inno или я чего-то не знаю об экранировании одиночных кавычек?
Root: HKLM; SubKey: Microsoft\Windows\CurrentVersion\Control Panel\don't load; ValueType: string; ValueName: LClock.cpl; Components: soft\lclock; Flags: uninsdeletevalue

Nordek
28-01-2014, 16:53
XXXler, Ты SOFTWARE пропустил:
[Registry]
Root: HKLM; SubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\don't load; ValueType: string; ValueName: LClock.cpl; Flags: Flags: uninsdeletevalue

Shkutu
28-01-2014, 18:12
Всем доброго времени суток!
А нет ли какого-нибудь примера по использованию эмуляции дефайнов/прагмы при компиляции из командной строки?
Надо передавать версию приложения через параметр в командной строке при компиляции, но не совсем понимаю, как это правильно сделать.




© OSzone.net 2001-2012