PDA

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


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

El Sanchez
12-10-2012, 17:23
Это именно утечка, вот только не понятно почему... »
Serega, это память, отводимая для функции обратного вызова. Если вызвать CallbackAddr один раз, результат поместить в глобальную переменную и работать потом только с ней, то память скакнет только раз.

SatHan
12-10-2012, 21:00
Это именно утечка, вот только не понятно почему... »
тоже самое происходит при закрытии/завершении инсталятора. о чём пытался донести из этого (http://forum.oszone.net/post-1980251-796.html) поста. хотя инсталятор простой. сделанный по дефолту мастера инно. ничем не напичкан не каких кодов. инсталятор завершил а из памяти ещё 2-3 секунды выгружается.

Respin
13-10-2012, 13:54
Спасибо.
много чего уж перепробовал, но оставил этот, так как код короче всех. потому шансов на ошибки мизерный. »

+1024
C использованием IsTask можно нарваться на параноидальный антивирь который блокирует вызов сторонних неизвестных неподписанных библиотек и dll (IsTask в их числе, ога), как следствие получить в инсталлере "Ошибка вызова xxx.dll" и краш инсталлера.
Самый рабочий вариант в моем посте. Не помню кто его мне накидал, или Serega или El Sanchez »

Просто может ему надо не только найти, но и "убить процесс"!?
Позволил себе немного доработать этот код (http://forum.oszone.net/post-1996882-1082.html), некаких .dll, а работает также как IsTask.
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program

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

[*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;
var
ResultCode: Integer;

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 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 InitializeSetup(): Boolean;
begin
Result:= True;
if IsProcessRunning('notepad.exe') then begin
if MsgBox('Блокнот запущен.'#13#10'Для продолжения установки нужно закрыть блокнот'#13#10'Закрыть блокнот сейчас?', mbError, MB_YESNO) = IDYES then
begin
Exec('cmd', '/C taskkill /f /im notepad.exe /t > nul', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
end else begin
MsgBox ('Закройте блокнот и запустите установку заново', mbCriticalError, MB_OK);
Result:= False;
end;
end;
end;

SatHan
13-10-2012, 17:15
Respin, Привет.
чего уж скрывать, поделюсь своей мыслью по этому поводу. главное расскажу зачем мне это нужно.
эта фишка как раз расчитана на антивирусы и фаерволы. если инсталятор находит любой запущенный процесс. то в данном случае выдаёт сообщение что есть запущенная программа защиты и закрывается сам инсталятор не прибегая к попытке закрыть антивирусную программу. поскольку это не возможно так как у многой защиты есть самозащита.
я мог бы применить хак на vbs который для меня пару лет назад писали но это будет не верным решением. так как эта штука убивает напрочь любую защиту (даже самозащита не помогает). что не один антивирус, фаервол и пр. пр. после этого не запустятся. что в итоге мой инсталятор будет являться как вредоносное ПО. по этому хотел поступить как можно проще.

Respin
13-10-2012, 19:42
Знающие люди! Если вы когда-нибудь сталкивались или делали такую задачу, помогите, пожалуйста.
Как в кустомном Edit ограничить число символов? То есть чтобы минимум нужно ввести 4 и максимум 12 и после этого сконвертировать текст в UTF 8 (соответственно в файл INI).
Когда это знаешь - всё просто, а когда ни разу с этим не сталкивался - это кажется недостижимым.
SatHan, Привет.
Я думал тебе надо какую-то другую программу закрыть, без использования сторонних .dll-ок.
А ты значит собираешься "антивири" вырубать :nunchaku: Твоими инсталляторами я пользоваться не буду :teeth:

SatHan
13-10-2012, 20:49
А ты значит собираешься "антивири" вырубать»как раз таки не хочу чтоб инсталятор вырубал защиту. наоборот. нужно чтоб при нахождении защиты инсталятор выдал сообщение что "не может продолжить установку из-за запущенного антивируса, фаервола" и закрывался а защита осталась не тронута.

Mailchik
13-10-2012, 23:27
Как в кустомном Edit ограничить число символов? То есть чтобы минимум нужно ввести 4 и максимум 12 и после этого сконвертировать текст в UTF 8 (соответственно в файл INI).
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Code]
var
TestEdit : TCustomEdit;
TestCheckBox : TCheckBox;
//----- Конвертирование в UTF-8-----Начало\\
const
CP_ACP = 0;
CP_UTF8 = 65001;

function MultiByteToWideChar(CodePage: UINT; dwFlags: DWORD; lpMultiByteStr: PAnsiChar; cbMultiByte: Integer; lpWideCharStr: PAnsiChar; cchWideChar: Integer): Longint;
external 'MultiByteToWideChar@kernel32.dll stdcall';
function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD; lpWideCharStr: PAnsiChar; cchWideChar: Integer; lpMultiByteStr: PAnsiChar; cbMultiByte, lpDefaultChar, lpUsedDefaultChar: Integer): Longint;
external 'WideCharToMultiByte@kernel32.dll stdcall';

function StringToWideString(const aStr: String; codePage: Word): String;
var
len: Integer;
begin
len := MultiByteToWideChar(codePage, 0, aStr, -1, '', 0);
if len > 0 then
begin
SetLength(Result, (len*2)-2);
MultiByteToWideChar(codePage, 0, aStr, -1, Result, Length(Result));
end;
end;

function WideStringToString(const wStr: String; codePage: Word): String;
var
len: Integer;
begin
len := WideCharToMultiByte(codePage, 0, wStr, -1, '', 0, 0, 0);
if len > 0 then
begin
SetLength(Result, len-1);
WideCharToMultiByte(codePage, 0, wStr, -1, Result, Length(Result), 0, 0);
end;
end;

function SetNickname(Nickname: String; IsConvert: Boolean): String;
begin
Result := Nickname;
if IsConvert then Result := WideStringToString(StringToWideString(Result, CP_ACP), CP_UTF8);
end;
//----- Конвертирование в UTF-8-----Конец\\

procedure InitializeWizard;
begin
with WizardForm do begin
OuterNotebook.Hide;
end;

TestEdit := TCustomEdit.Create(WizardForm);
with TestEdit do begin
Parent := WizardForm;
Left := ScaleX(150);
Top := ScaleY(200);
Width := ScaleX(150);
end;

TestCheckBox := TCheckBox.Create(WizardForm);
with TestCheckBox do begin
Parent := WizardForm;
Width := ScaleX(150);
Left := ScaleX(150);
Top := ScaleY(230);
Checked := True;
Caption := 'Конвертировать в UTF-8';
end;
end;

function NextButtonClick(CurPageID : Integer) : Boolean;
begin
Result := True;
if (CurPageId = wpWelcome) then if
(Length(TestEdit.Text) < 4) or (Length(TestEdit.Text) > 12) then begin //Если длина меньше 4 и больше 12 символов
MsgBox('минимум нужно ввести 4 и максимум 12', mbInformation, MB_OK); //то переход не выполнится
Result := False end else begin
SetIniString('Settings', 'PlayerName', SetNickname(TestEdit.Text, TestCheckBox.Checked), ExpandConstant('{src}\test.ini')); //конвертирование в utf-8
end;
end;
Пример конвертирования в utf-8 заимствован у El Sanchez'а.

SARATOVSKY
14-10-2012, 02:51
Здравствуйте! У меня инсталл с 3-мя компонентами и один из этих компонентов с флагом "фиксирован( fixed)", так как сделать так, что-бы если этот компонент уже установлен при первой инсталляции, то все последующие инсталляции он не устанавливался, а пропускался, так как это отнимает время! P.S. использую архивы фри арк и скрипт исДоне! Спасибо!

Respin
14-10-2012, 10:19
Mailchik, Благодарю.

то все последующие инсталляции он не устанавливался, а пропускался »
Не совсем понятно, какие последующие инсталляции... Если пользователь удалит программу, то его же вновь придётся установить.
Как вариант: К нему нужно прописать ключ реестра (и потом не удалять этот ключ)...
[Components]
Name: "Component"; Description: "Мой компонент"; Flags: fixed; Check: MyComponent;

[Registry]
Root: HKLM; Subkey: "Software\MyProgram\MyComponent";

function MyComponent: Boolean;
begin
if RegKeyExists(HKLM, 'Software\MyProgram\MyComponent;')
then
Result:= False;
end;

Если ключ имеется, то компонент не будет видно вообще.
P.S. На FreeArc-ке и ISDone не проверял (будет ли он архив распаковывать или нет).

SARATOVSKY
14-10-2012, 15:41
Respin, Спасибо!

LinkOFF
15-10-2012, 02:00
Доброй ночи. Подскажите: как сделать так, чтобы после установки заносились ключи в реестр и с последующим запуском инсталляции было сообщение "Программа уже установлена." и выскакивал запрос на деинсталляцию?

Johny777
15-10-2012, 02:57
LinkOFF, фапай код: :)


[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

AppId=The_Best_AppId

[ code]
function InitializeSetup(): Boolean;
var
AppPath, UninsPath: string;
ResultCode: Integer;
begin
AppPath := RemoveQuotes(ExpandConstant('{reg:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSe tting("AppID")}_is1,InstallLocation|}'));
UninsPath := RemoveQuotes(ExpandConstant('{reg:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSe tting("AppID")}_is1,UninstallString|}'));

if (AppPath <> '') then
begin
Result := MsgBox('Программа установлена' +#13#10+ 'Удалить?', mbError, MB_YESNO) = IDNO;
if not Result then Exec(UninsPath, '', '' , SW_SHOW, ewNoWait, ResultCode);
end else Result := True;
end;

поставь где-нибудь El Sanchez-у спасибо, тк дёрнул значения переменных из его кода авторана халфы!

LinkOFF
15-10-2012, 03:04
Johny777, а почему пишет "unknown identifier 'Result'

а все решил проблему

LinkOFF
15-10-2012, 03:21
Johny777, не не встает

Robby
15-10-2012, 10:45
Есть инсталлятор который устанавливает программу, к программе идет xml файл настроек. В файле настроек в конце установки нужно прописать пути к нескольким папкам. Проблема кроется в русских буквах, и заключается в следующем: программа работает с кодировкой символов CP1252 (ISO 8859-1) при этом проблем с русскими буквами она не имеет, но в файле настроек путь должен выглядеть вот так C:\Documents and Settings\Admin\Ìîè äîêóìåíòû\ а не так C:\Documents and Settings\Admin\Мои документы\. Вопрос в следующем как перекодировать CP1251 в CP1252? В общем нужна функция которая на входе получает строку в кодировке CP1251 и возвращает ее в кодировке CP1252.

insombia
17-10-2012, 16:44
как сделать чтобы исдон распаковывал файлы через секцию run? где-то видел такое

LagunaFAN
17-10-2012, 17:40
Всем добрый день! Имею проблему :( Для своих нужно хочется реализовать следующее:

2 типа инсталляции - обычная установка и установка в стим. С обычной установкой все понятно. А вот с установкой в стим затык :(

Допустим, есть 2 установщика - setup.exe (обычная установка) и steamsetup.exe (установка в стим).

Steamsetup.exe имеет свой путь установки непосредственно в стим. Хочется, чтобы на стадии инсталляции он запускал setup.exe, а тот распаковывал файлы по тому пути, который ему сообщит steamsetup.exe .

Подскажите, пожалуйста, как можно реализовать такое?

Ребят, я слаб в паскале, поэтому дико прошу помощи! Заранее благодарю!

Respin
17-10-2012, 19:47
как сделать чтобы исдон распаковывал файлы через секцию run? »
Файлы чего именно?

Допустим, есть 2 установщика - setup.exe (обычная установка) и steamsetup.exe (установка в стим).
Steamsetup.exe имеет свой путь установки непосредственно в стим. Хочется, чтобы на стадии инсталляции он запускал setup.exe, а тот распаковывал файлы по тому пути, который ему сообщит steamsetup.exe . »

А по какому пути распаковывается Steamsetup.exe?
Не проще ли сделать один установщик и для... и для того?

LagunaFAN
17-10-2012, 20:34
А по какому пути распаковывается Steamsetup.exe?
Не проще ли сделать один установщик и для... и для того? »
Например, по такому C:\Steam\steamapps\common\unknown game

А насчет запихнуть все в один установщик... Быть может это и проще, но я незнаю как :unsure: :blush: :blush:

Respin
17-10-2012, 21:58
Например, по такому C:\Steam\steamapps\common\unknown game »
Вы уже всё распланировали (что будет два установщика (один из которых будет искать Steam + путь установки)). И всё же говорите примерно...
Ну значит, примерно, как-то так:
Два в одном.
[Setup]
AppName=unknown game
AppVerName=unknown ver game
AppVersion=unknown game version
DefaultDirName={pf}\unknown game
DefaultGroupName=unknown game
PrivilegesRequired=lowest

[_Code]
procedure InitializeWizard();
begin
if RegKeyExists(HKLM, 'Software\Valve\Steam') then
begin
WizardForm.DirEdit.Text:= ExpandConstant('{reg:HKLM\Software\Valve\Steam,InstallPath}\steamapps\common\unknown game');
WizardForm.DirBrowseButton.Hide;
end;
end;




© OSzone.net 2001-2012