Ru-Board.club
← Вернуться в раздел «Программы»

» Inno Setup (создание инсталяционных пакетов)

Автор: boss911
Дата сообщения: 23.07.2008 23:06
serg_aka_lain

Цитата:
if RegValueExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0C01E81B-A528-4EB8-AFA0-415F4401F7E3}_is1','UninstallString') then

Оно проверяет значение в данном ключе. А можно, чтобы оно проверяло просто наличие ключа, а не значения в нем?
Автор: serg_aka_lain
Дата сообщения: 23.07.2008 23:14
boss911

Цитата:
наличие ключа

if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0C01E81B-A528-4EB8-AFA0-415F4401F7E3}_is1') then
Автор: boss911
Дата сообщения: 23.07.2008 23:30
serg_aka_lain

[more]procedure CurPageChanged(CurPageID: Integer);
begin
UpdateWizardButton(WizardForm.BackButton,bidBack)
UpdateWizardButton(WizardForm.NextButton,bidNext)
UpdateWizardButton(WizardForm.CancelButton,bidCancel)
begin
if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MY KEY) then
if CurPageID = wpSelectTasks then
WizardForm.TasksList.ItemEnabled[3]:= False;
end;
end;[/more]

Короче не пашет, третий чекбокс активен (все активны), данная ветка в реестре присутствует на момент установки приложения.

Добавлено:
Вот что выяснил: оно не срабатывает на тех чекбоксах, где сстоит флаг unchecked и указано описание группы GroupDescription. Как исправить?
Автор: serg_aka_lain
Дата сообщения: 23.07.2008 23:39
boss911

Цитата:
Короче не пашет, третий чекбокс активен (все активны


Третья линия не значит что это третий checkbox

На примере этого кода

[Tasks]
Name: desktopicon; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:";
Name: desktopicon\common; Description: "For all users"; GroupDescription: "Additional icons:"; Flags: exclusive
Name: desktopicon\user; Description: "For the current user only"; GroupDescription: "Additional icons:"; Flags: exclusive unchecked
Name: quicklaunchicon; Description: "Create a &Quick Launch icon"; GroupDescription: "Additional icons:"; Flags: unchecked
Name: associate; Description: "&Associate files"; GroupDescription: "Other tasks:"; Flags: unchecked

- третий checkbox будет (Name: desktopicon\user;), Так как ( GroupDescription: "Additional icons:";) тоже линия и счет идет с нуля Item[0]. и с unchecked всё в порядке.

Автор: boss911
Дата сообщения: 23.07.2008 23:44
serg_aka_lain

Цитата:
Третья линия не значит что это третий checkbox

Буквально несколько секунд назад до меня это дошло, методом тыка.

Как можно поменять цвет текста не активного чекбокса? Я просто юзаю скин "Slate" и оно не совсем там смотрится.
Автор: serg_aka_lain
Дата сообщения: 24.07.2008 00:08
boss911
Так как ( GroupDescription: "Additional icons:";) тоже линия и счет идет с нуля Item[0]. и с unchecked всё в порядке.

Если не использовать GroupDescription

Name: desktopicon; Description: "Create a &desktop icon";
Name: desktopicon\common; Description: "For all users"; Flags: exclusive
Name: desktopicon\user; Description: "For the current user only"; Flags: exclusive unchecked

- вторым будет Name: desktopicon\user;
Автор: boss911
Дата сообщения: 24.07.2008 00:18
serg_aka_lain

Та то я уже все понял, что любая строка в TasksList защитывается.

Мне бы вот:

Цитата:
Как можно поменять цвет текста не активного чекбокса? Я просто юзаю скин "Slate" и оно не совсем там смотрится.

А также хочется поменять цвет текста GroupDescription, все в том же скине "Slate".
Автор: Artem_Butenko
Дата сообщения: 24.07.2008 01:41
Здравствуйте товарищи, я со своими вопросами из предыдущего поста, может кто-нибудь сталкивался с подобным? Пожалуйста помогите.
Автор: boss911
Дата сообщения: 24.07.2008 02:02
Помогите добавить в этот [more=кусок кода]
Код: procedure CurStepChanged(CurStep: TSetupStep);
if CurStep = ssPostInstall then
begin
if IsTaskSelected('MyTask') = False then
begin
DelTree(ExpandConstant('{app}') + '\', True, True, True);
добавить функцию удаления ключа в реестре
end;
end;
Автор: Sampron
Дата сообщения: 24.07.2008 02:19
Artem_Butenko
В инно нет такого контрола как GroupBox, но можешь попробовать [more=так]
[_Code]
procedure InitializeWizard();
var
Panel: TPanel;
Text: TNewStaticText;
begin
Panel:=TPanel.Create(WizardForm)
Panel.SetBounds(0,130,417,60)
Panel.BevelInner:=bvLowered
Panel.Parent:=WizardForm.SelectDirPage

Text:=TNewStaticText.Create(WizardForm)
Text.Left:=Panel.Left + 10
Text.Top:=Panel.Top + -5
Text.Font.Color:=clBlue
Text.Caption:='Папка установки'
Text.Parent:=WizardForm.SelectDirPage

WizardForm.DirEdit.SetBounds(10,20,307,21)
WizardForm.DirEdit.Parent:=Panel

WizardForm.DirBrowseButton.SetBounds(327,19,80,23)
WizardForm.DirBrowseButton.Parent:=Panel
end;
[/more]

Добавлено:
boss911
RegDeleteKeyIncludingSubkeys(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\My Program_is1')
DeleteFile(ExpandConstant('{app}\unins000.dat'))
DeleteFile(ExpandConstant('{app}\unins000.exe'))
Автор: boss911
Дата сообщения: 24.07.2008 03:25
Sampron

А я с дуру лепил это:

Код: RegDeleteKeyIfEmpty(const RootKey: Integer; const SubkeyName: String): Boolean;
Автор: Victor_Dobrov
Дата сообщения: 24.07.2008 03:29
ComradG

Цитата:
реализовать имитацию страницы выбора компонентов на подобие инсталлеров NSIS?

Три примера есть в коллекции скриптов из Шапки.
Автор: boss911
Дата сообщения: 24.07.2008 03:55
А есть ли нечто подобное:

Код: [Registry]
Root: HKLM; SubKey: SOFTWARE\{AppVerName}; ValueType: none
Автор: Victor_Dobrov
Дата сообщения: 24.07.2008 10:54
Как известно, деинсталлятор не восстанавливает значения параметров реестра, он может их только удалить или оставить.
Поэтому предлагаю [more=скрипт RegBackup]
[Setup]
AppName=RegBackup
AppVerName=Registry Backup
CreateAppDir=false

[Registry]
Root: HKCU; SubKey: Control Panel\Desktop; ValueType: none; ValueName: Wallpaper; Flags: deletevalue; BeforeInstall: RegBackup('HKCU\Control Panel\Desktop')

[Run]
Filename: {uninstallexe}; Flags: nowait postinstall; Description: Восстановить обои Рабочего стола

[Code]
function SystemParametersInfo(uAction, uParam: integer; pvParam: longint; fUpdateProfile: integer): boolean; external 'SystemParametersInfoA@user32';

// Зарезервировать параметры указанного раздела реестра или Восстановить записи реестра из резервной копии
Procedure RegBackup(Path: String); var errCode, n: Integer; RegExe, isKey: String; Keys: TArrayOfString; Begin
RegExe:= AddBackslash(GetSystemDir) + 'reg.exe'
if not FileExists(RegExe) then begin MsgBox('Registry backup not created' #13#10 'File reg.exe not found!', mbError, MB_OK); Exit end;
    isKey:= 'HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting('AppName')}_regBackup'    {! InnoSetup удаляет чужие ключи в AppName_is1}
    if Length(Path) > 0 then
        Exec(RegExe,'copy '+ AddQuotes(Path) +' '+ AddQuotes(AddBackslash(isKey) + Path) +' /s /f','',sw_HIDE, ewWaitUntilTerminated, errCode)
    else begin
        if not RegGetSubkeyNames(HKLM, Copy(isKey, 6,Length(isKey)), Keys) then Exit; { нет резервных записей}
    for n:= 0 to GetArrayLength(Keys) -1 do    { reg.exe не может сохранять в корень реестра}
        Exec(RegExe, 'copy '+ AddQuotes(AddBackslash(isKey) + Keys[n]) +' '+ Keys[n] +' /s /f','', sw_HIDE, ewWaitUntilTerminated, errCode)
    RegDeleteKeyIncludingSubkeys(HKLM, Copy(isKey, 6,Length(isKey)))
    end;
End;

Procedure CurStepChanged(CurStep: TSetupStep);
Begin
if CurStep = ssPostInstall then SystemParametersInfo(20,0,0,2) { update Desktop}
End;

Procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);    Begin
    if CurUninstallStep = usPostUninstall then begin RegBackup(''); SystemParametersInfo(20,0,0,2) end
End;
[/more]
, показывающий, как восстановить прежние значения реестра при удалении программы.

Это может пригодится в инсталляторах, которые изменяют настройки системы или других программ.

boss911 - используй препроцессор, который работает перед компиляцией: {#SetupSetting("AppVerName")}
Автор: 0bject
Дата сообщения: 24.07.2008 14:11
Приветствую всех. Проблема следущая:
Создаю текстовый файл при помощи функции SaveStringToFile. Созданный файл имеет кодировку ANSI, а мне необходимо Unicode.
Существуют ли какие-либо стандартные методы решения данной задачи?

Пробовал делать так, но результат не изменился:
Создал функцию для конвертации строки
function WinToDos( s: string ): string;
var
str: string;
begin
str := s;
CharToOemBuff( str );
Result := str;
end;

В момент записи в файл конвертировал строку
SaveStringToFile( FilePath, WinToDos( 'text1' ) + #13#10, False );
SaveStringToFile( FilePath, WinToDos( 'text2' ) , True );

Автор: Unc1e
Дата сообщения: 24.07.2008 16:25
0bject, я ведь совсем недавно спрашивал. Переделай [more=скрипт][Setup]
AppName=My Program
AppVerName=My Program version 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program

[Files]
Source: "filename.txt"; DestDir: "{app}"

[no][Code][/no]
FUNCTION MultiByteToWideChar(CodePage: INTEGER; dwFlags: INTEGER; lpMultiByteStr: STRING; cbMultiByte: INTEGER; VAR lpWideCharStr: STRING; cchWideChar: INTEGER): INTEGER;
EXTERNAL 'MultiByteToWideChar@kernel32.dll stdcall';

FUNCTION WideString(BString: STRING): STRING;
VAR
I: INTEGER;
WString: STRING;
BEGIN
WString:='';
FOR I:=1 TO LENGTH(BString) DO BEGIN
WString:=WString+Copy(BString,I,1)+CHR(0);
END;
WString:=WString+CHR(0)+CHR(0);
RESULT:=WString;
END;

procedure CurStepChanged(CurStep: TSetupStep);
var
S: String;
begin
If CurStep=ssPostInstall then
begin
LoadStringFromFile(ExpandConstant('{app}\filename.txt'), S)
DeleteFile(ExpandConstant('{app}\filename.txt'));
S:=WideString(S)
SaveStringToFile(ExpandConstant('{app}')+'\filename.ini', S, true);
end;
end;

[UninstallDelete]
Type: files; Name: "{app}\filename.ini"[/more] под себя.
Автор: boss911
Дата сообщения: 24.07.2008 17:07
Victor_Dobrov

Цитата:
используй препроцессор, который работает перед компиляцией: {#SetupSetting("AppVerName")}

Ой, я не понимать, дай, плиз, полный пример, как сделать подобное:

Код: [Registry]
Root: HKLM; SubKey: SOFTWARE\{AppVerName}; ValueType: none
Автор: Genri
Дата сообщения: 24.07.2008 18:51
Unc1e

Цитата:
я ведь совсем недавно спрашивал
-- где спрашивал? Видно я как-то пропустил этот вопрос.
Дело в том, что указанный тобой пример, конвертит не совсем в юникод. С другой стороны, судя по наличию в примере объявления функции MultiByteToWideChar, ход мысли очевидно был правильный Кстати, а почему не стал делать через MultiByteToWideChar?

0bject

Цитата:
файл имеет кодировку ANSI, а мне необходимо Unicode
...............
Создал функцию для конвертации строки
function WinToDos
-- так все-таки, сконвертировать надо в юникод или в дос? Если первое, то смотри [more=пример]
[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program

[_Code]
function MultiByteToWideChar(CodePage: UINT; dwFlags: DWORD; lpMultiByteStr: string;
cbMultiByte: integer; lpWideCharStr: string; cchWideChar: integer): integer;
external 'MultiByteToWideChar@Kernel32.dll stdcall';

var
str1, str2, wstr: string;
res: integer;

procedure InitializeWizard();
begin
LoadStringFromFile('C:\TMP\ansi1.txt', str1);
LoadStringFromFile('C:\TMP\ansi2.txt', str2);
str1:= str1+str2;

res:= MultiByteToWideChar(0, 0, str1, (-1), wstr, 0);
wstr:= StringOfChar(#0, res*2 - 2);
res:= MultiByteToWideChar(0, 0, str1, (-1), wstr, res);
wstr:= Chr($FF) + Chr($FE) + wstr;
SaveStringToFile('C:\TMP\unicode2.txt', wstr, False);
end;
[/more] Правда, пример весьма условный (без проверок и пр.). Но принцип, думаю понятен.
Автор: Unc1e
Дата сообщения: 24.07.2008 19:24
Genri, вот тут спрашивал.
Цитата:
а почему не стал делать через MultiByteToWideChar?
Потому что в Паскале еле-еле разбираюсь
Цитата:
Видно я как-то пропустил этот вопрос.
Да уж, Вы что-то редко к нам заглядываете Вот с этим не поможете?
Автор: Genri
Дата сообщения: 24.07.2008 21:31
Unc1e

Цитата:
Вот с этим не поможете?
-- замени везде
AddApplicationToExceptionListW на
AddApplicationToExceptionListA
а так же
RemoveApplicationFromExceptionListW на
RemoveApplicationFromExceptionListA

hint! W - это не от Windows а от WideString; А - от AnsiString
В принципе можно и сконвертировать (см.выше). Но раз есть готовая, то особого смысла нет.


Цитата:
в Паскале еле-еле разбираюсь
-- я тоже
Автор: boss911
Дата сообщения: 24.07.2008 21:53

Код: [Registry]
Root: HKLM; SubKey: "SOFTWARE\{#SetupSetting("AppVerName")}"; ValueType: none; Check: not IsTaskSelected('TASK')
Автор: Unc1e
Дата сообщения: 24.07.2008 22:02
Genri, как все просто оказалось... В очередной раз благодарю!
Автор: 0bject
Дата сообщения: 25.07.2008 06:51
Спасибо всем. Вышел из ситуации быстренько сделав библиотеку с необходимым функционалом. [more]library iss_SikeDemo;

uses
Windows, ADODB, frxUnicodeUtils;

procedure CreateUDL(UdlName: string; DBname: String; ServerName: String; Login: String; AuthWin: Boolean); stdcall;
var
ps: WideString;
begin
ps := '[oledb]' + #13#10 +
'Provider=SQLOLEDB.1;' +
'Integrated Security=SSPI;' +
'Persist Security Info=False;' +
'Initial Catalog=' + DBname + ';' +
'Data Source=' + ServerName;
with TWideStrings.Create do
begin
Text := WideChar( #65279 ) + WideString( ps );
SaveToFile( UdlName );
Free;
end;
end;

exports CreateUDL;

begin
end.[/more]

Теперь проблема в другом:
Слишком долго выполняется процедура из этой DLL.
Попробую предложенный Вами пример.

________
Добавлено несколько минут спустя:
Вот функцию сделал (так удобнее)

function AnsiToUnicode( str: string ): string;
var
res: integer;
wstr: string;
begin
res := MultiByteToWideChar( 0, 0, str, (-1), wstr, 0 );
wstr := StringOfChar( #0, res*2 - 2 );
res := MultiByteToWideChar( 0, 0, str, (-1), wstr, res );
Result := Chr( $FF ) + Chr( $FE ) + wstr;
end;

Работает также медленно как и моя DLL,
единственный плюс в отсутствии необходимости иметь самописную DLL.

Подскажите как в момент выполнения "долгой" функции/процедуры отобразить "живой" ProgressBar. Иными словами: возможно ли выполнение чего-либо в отдельном потоке? Ели возможно, то пример где посмотреть?




Добавлено:
Многие из здесь присутствующих наверняка знают что такое 'msconfig', а кроме 'cd..', 'dir', 'ping' знают еще несколько магических слов из черного окна.
Поэтому поздравляю всех с днем системного администратора.

Желаю счастья, здоровья, семейного тепла и уюта!
Автор: Genri
Дата сообщения: 25.07.2008 09:42
0bject

Цитата:
долго выполняется процедура из этой DLL
.....
Работает также медленно как и моя DLL
-- уверен, что проблема именно в этой части? Может, время занимает подготовка данных для конвертации? Попробуй проверить, примерно так:
MsgBox('ps: ' + ps, mbInformation, MB_OK);
wps:= AnsiToUnicode(ps);
MsgBox('Converted!', mbInformation, MB_OK);
SaveStringToFile('C:\TEMP\unicode2.txt', wps, False);
MsgBox('Saved!', mbInformation, MB_OK);

Автор: antifire
Дата сообщения: 25.07.2008 13:32
Всем привет! Столкнулся с следующим - в секции [Setup] я прописал DefaultDirName={pf}\my_prog , но по каким то причинам на некторых компах, куда уже устанавливали прогу не в Program Files, по умолчанию устанавливает не в C:\Program Files\my_prog а куданибудь еще например D:\Новая папка\my_prog. Я так понял, где то в кеше остаеться информация, откуда инсталятор её берет. Как более жестко прописать в [Setup] путь по устаноке? Что нибудь вроде %SysDrive%\Program Files\my_prog?
Автор: elapse
Дата сообщения: 25.07.2008 13:37
antifire, может, лучше использовать директиву UsePreviousAppDir=no в секции [Setup]?
Автор: antifire
Дата сообщения: 25.07.2008 13:52
elapse
Ага, спасибо, помогло. =)

Добавлено:
Еще вопрос.
Мой установщик содержит в себе файл prog.ini (который отвечает за настройки программы, которую устанавливают) Содержимое prog.ini в начале:
[Directories]
Structures=C:\Program Files\my_prog\
Bodies=C:\Program Files\my_prog\
Возможно ли сделать так, чтобы эти пути менялись в зависимости от того, какой путь выбирают для установки программы? То есть если захочется установить на D:\program\my_prog\ то в этой папке файл prog.ini будет содержать
[Directories]
Structures=D:\program\my_prog\
Bodies=D:\program\my_prog\

Автор: laskeev2
Дата сообщения: 25.07.2008 14:33
1. Скажите, можно ли сделать имя файла, который должен включаться в проект, переменной? У меня не получается именно имена файлов сделать переменными.

Т.е. вместо readme_fr.txt использовать переменную (или самим innosetup-ом или через code):
Source: readme_fr.txt; DestName: {code:MyReadmeFile}; DestDir: "{app}"; Flags: isreadme

2. Так и не разобрался, как работать с юникодом - надо, чтобы присутствовали юникодовские символы в названии программы:
Name: {group}\Здесь надо, чтобы было название с юникодовыми символами; Filename: {app}\file.exe; WorkingDir: {app}

Как это сделать?
Автор: 0bject
Дата сообщения: 25.07.2008 15:22

Цитата:
Попробуй проверить ...

Genri, ты прав. Спасибо.
Стал смотреть и действительно, подвисание появлялось раньше и юникод здесь не причем.

А проблема была в долгом выполнении функции EXEC.
Если просто выставить параметр Wait=ewNoWait (не ждать завершения процесса), то не исключена ситуация когда инсталляция закончится быстрее чем вышеупомянутый Exec и автоматически запуск устанавливаемой программы приведет к ошибке.

с IS знаком всего пару дней, поэтому пока так вышел из ситуации:
во избежании подвисаний запускаю Exec с параметром ewNoWait, но следом делаю пустой цикл, в котором "двигаю" ProgressBar.

Код:
...
...
ExecResult := Exec( RestoreCmdPath, '', '', SW_HIDE , ewNoWait, ResultCode);
ProgressPage := CreateOutputProgressPage('Установка...', 'Развертывание базы данных');
ProgressPage.SetText('Копируется информация...', '');
ProgressPage.SetProgress(0, 0);
ProgressPage.Show;
try
for i := 0 to 50 do begin
ProgressPage.SetProgress(i, 50);
Sleep(100);
end;
finally
ProgressPage.Hide;
end;
...
...
...
Автор: Diawer
Дата сообщения: 25.07.2008 16:36
ZheKA767

Цитата:
Для Обзора папок
function DirBrowseButtonClick(CurPageID: Integer): Boolean;
begin
sndPlaySound(ExpandConstant('{tmp}\click.wav'), $0001);
Result := True;
end;

Для пуска
function GroupBrowseButtonClick(CurPageID: Integer): Boolean;
begin
sndPlaySound(ExpandConstant('{tmp}\click.wav'), $0001);
Result := True;
end;

я пробовал, но почему-то с остальным вместе не [more=катит]

[Files]
Source: click.wav; DestDir: {tmp}; Flags: dontcopy nocompression;

[Code]
function sndPlaySound(lpszSoundName: string; uFlags: cardinal):integer;
external 'sndPlaySoundA@winmm.dll stdcall';

function InitializeSetup(): Boolean;
begin
ExtractTemporaryFile('click.wav');
Result := True;
end;

function DirBrowseButtonClick(CurPageID: Integer): Boolean;
begin
sndPlaySound(ExpandConstant('{tmp}\click.wav'), $0001);
Result := True;
end;

function GroupBrowseButtonClick(CurPageID: Integer): Boolean;
begin
sndPlaySound(ExpandConstant('{tmp}\click.wav'), $0001);
Result := True;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
sndPlaySound(ExpandConstant('{tmp}\click.wav'), $0001);
Result := True;
end;

function BackButtonClick(CurPageID: Integer): Boolean;
begin
sndPlaySound(ExpandConstant('{tmp}\click.wav'), $0001);
Result := True;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
sndPlaySound(ExpandConstant('{tmp}\click.wav'), $0001);
end;
[/more]

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970

Предыдущая тема: Презентация


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.