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

Статус
В этой теме нельзя размещать новые ответы.

sergey3695

Ветеран
Модератор
Может кто-нибудь знает,как сделать чтобы при разворачивании формы со скином,она не мигала? :unknown: может дело в библе?
 

LexBell

Борода
Супер модератор
sergey3695, я ранее публиковал где-то решение от Leserg для надписей в юникодной инно.
Всем привет!

Захотелось мне как-то собрать к одной программе инсталлятор с помощью программы Inno Setup. Как известно, этот установщик выпускается в двух редакциях: ANSI и Unicode. В отличии от ANSI, редакция Unicode позволяет создать инсталляторы, язык интерфейса которых будет всегда верно отображаться на системе пользователя, независимо от региональных установок. Исходя из соображений того, что система у меня дойч, а проверять и отлаживать работу установщика как-то необходимо, то я выбрал Unicode версию программы и приступил к работе. С помощью простенького мастера создания инсталляторов, который идет вместе с программой, можно быстро собрать простейший установщик. Но мне этого оказалось недостаточно. Необходимо было решать дополнительные задачи в процессе установки ПО, плюс хотелось наделить сам инсталлятор некоторыми особенностями, например отображения дополнительного кликабельного текста. С помощью описанных здесь примеров, а также примеров собранных на просторах сети Интернет, удалось решить все задачи, которые я для себя по-напридумывал.

Но вот при отладке инсталляторе я столкнулся с неприятным сюрпризом. Те из вас, кто пользуется ANSI версией Inno Setup, далее могут не читать, т.к. эта информация касается только особенностей Unicode версии.


Итак, как вы знаете, если требуется в инсталляторе решать какие-то дополнительные задачи, будь-то по оформлению или по функциональности, необходимо в сценарии инсталлятора писать соответствующий код.

Например, я добавил текстовую метку на диалоги:



А вот одна из функций, которая выдает пользователю сообщение, если указана неверная папка установки:



Как видите, строки имеют текст на русском языке. На ОС Windows, где системным языком является русский (или язык кириллической группы) никаких проблем в работающем инсталляторе пользователь не увидит - все сообщения и строки будут отображены верно. Совсем другая картина будет при запуске инсталлятора на системе, где системный язык не русский. Стандартные сообщения и строки, заложенные разработчиками будут отображены верно, но вот строки, которые были описаны в сценарии, будут выглядеть кракозябрами:



"Вот блин! Что за ерунда! - подумал я, - Версия Unicode, а кириллица поддерживается не полностью." Еще раз повторю, что на русскоязычных системах никаких проблем нет. В принципе, можно было бы не заморачиваться с этим вопросом и оставить его так. Подавляющее большинство русскоязычных пользователей сидят на русских системах. Но все же, есть небольшой процент тех (и я в их числе), которые в силу каких-то причин или обстоятельств пользуются не русскими системами. Лично мне неприятно смотреть на такое безобразие в инсталляторах, поэтому решил довести до ума. Первым делом заглянул в справку Inno Setup. Ответ нашелся почти сразу, вот он:



Говоря русским языком: "Любые юникодные символы в сценарии всегда конвертируются в ANSI и не могут быть отображены юникодом. Чтобы отобразить юникодный текст, его необходимо записать НЕХ-кодами или использовать функцию LoadStringsFromFile." Да уж, дела... Пользоваться функцией мне не позволил мой уровень знаний Inno Setup, а вот конвертировать текст в шестнадцатиричный юникод - это я уже проходил. Довольно много программ использует это принцип и при их переводе им не раз приходилось пользоваться. Только для Inno требовался немного другой синтаксис.

Например, слово "Привет" в НЕХ юникоде выглядит так: \u041f\u0440\u0438\u0432\u0435\u0442

Для сценария Inno Setup его нужно записать так: #$041f#$0440#$0438#$0432#$0435#$0442

Т.е. вместо символов "\u" необходимо подставить "#$". Конвертировать текст можно в текстовом редакторе PSPad. Затем выполнить замену указанных символов по всему тексту и вставить в сценарий. Вот и вся технология.

Проделав эту операцию со всеми необходимыми строками в своем сценарии, я получил следующее:





Ну как вам шифровочка? В результате, при запуске готового инсталлятора на не русской системе, мы увидим знакомые буковки, которые приятно радуют наш глаз. :)



Задачка решена.

Тут же, как говорится, не отходя от кассы, набросал небольшую утилиту, которая конвертирует текст по заданному для Inno формату в юникодные НЕХ значения. Авось на будущее пригодится.



Написана на С#, поэтому для своей работы требуется установленный Microsoft .NET Framework Version 2.0 или выше. Программка прикреплена к этой новости.

Спасибо за внимание.

АNSI-2-HEX.7z
 
Последнее редактирование:

Devils Night

Ветеран



Вышла финальная версия: Inno Script Studio 2.0.0.17

[HR][/HR]Ссылки:
Инсталлятор: Скачать
Языковые пакеты: French | Russian | Polish

Внутри инсталлятора уже имеются:
3 языка: French, Polish и Russian
3 растровых изображения: SakuraSmall, SakuraSmall2 и SakuraWizard.
46 стилей: Chivalry, Chromium, Continuum, Contrast, Convergence, Crimson, CrystalBlue, DarkRealm, Dazzle, DeepSix, Destiny, Dreams, Elegance, Elusive, EveningMist, ForestGreen, ForeverBlue, ForeverBlue2, GraySteel, Happiness, iCandy, Illusion, Legends, LegendsII, LegendsIII, LegendsIV, Logi, LonghornPro, LunarBlue, Luxor, Metallics, Mint, MysticDreams, NightShades, NightStorm, Nocturnal, Obsidian, OceanBreeze, OdessaXP, OutWorld, PitchBlack, QuickSilver, Radiance, Raptor, Sakura и Vista.
 

RameR

Новичок
Можно ли как-нибудь отредактировать мини-страницу "выйти из программы установки",
скрыть значок вопроса и текст отредактировать?
Использую скин Tiger.cjstyles, он весь черный, а вот на этой странице нижняя панель белая, это в скине править через Skin Builder? если не трудно что именно?, а то максимум я в скине прогресс-бар поменял!
Где-можно глянуть пример checkbox'a "Запустить игру" на странице завершения, вроде видел где-то, а найти не могу?
Заранее, Thanks!

sergey3695, Сейчас глянул у скина форма черная, а у сообщения о закрытия форма белая, подскажи как на своей форме сделать?
 
Последнее редактирование:

sergey3695

Ветеран
Модератор
Где-можно глянуть пример checkbox'a "Запустить игру" на странице завершения, вроде видел где-то, а найти не могу?
Можешь посмотреть в скрипте "Prototype" от Shegorat'a (готовые скрипты)
Насчет скина: все там нормально, просто надо сообщение о закрытии делать на своей форме
пример (без скина)
 

RameR

Новичок
Вытащил из скрипта Prototype чекбокс "Запустить игру" и все, что с ним связано...Запихал это все в свой: ругается зараза...
{app} учел! Ругается на строку:
Exec(ExpandConstant('{#AppRunningFile}'), '', '', SW_SHOWNORMAL, ewNoWait, ResultCode);

чекбокс "Запустить игру" и все, что с ним связано:

#define AppRunningFile "{app}\prototypef.exe"
[CustomMessages]
RUS.RunProgram=Запустить {#SetupSetting("AppName")}
Код:
var
 RunProgram: TCheckBox;
 RunProgramLabel: TLabel;

procedure LabelOnClick(Sender: TObject);
 begin
 case Sender of
  RunProgramLabel: begin RunProgram.Checked:= not RunProgram.Checked; end;
 end;
  end;

procedure DeinitializeSetup();
var ResultCode: Integer;
begin
  ShowWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 0);
  UnloadSkin();
  if (WizardForm.CurPageID=wpFinished) and (RunProgram.Checked) then
    Exec(ExpandConstant('{#AppRunningFile}'), '', '', SW_SHOWNORMAL, ewNoWait, ResultCode);
end;

procedure InitializeWizard();
begin
 RunProgram:= TCheckBox.Create(WizardForm);
  with RunProgram do
  begin
    Parent:= WizardForm;
    SetBounds(ScaleX(176), ScaleY(200), ScaleX(13), ScaleY(13))
    TabOrder:= 5;
    Checked:= True;
  end;
 RunProgramLabel:= TLabel.Create(WizardForm);
  with RunProgramLabel do
  begin
    Caption:=ExpandConstant('{cm:RunProgram}');
    SetBounds(ScaleX(196), ScaleY(200), ScaleX(150), ScaleY(13))
    Transparent := True;
    Parent:= WizardForm;
    OnClick:= @LabelOnClick;
  end;
   end;
 [/SPOILER]
 Можно ли это заменить на function InitializeSetup(): Boolean; вместе с "{app}\prototypef.exe" без #define?  

#define AppRunningFile "{app}\prototypef.exe"

procedure DeinitializeSetup();
var ResultCode: Integer;
begin
  ShowWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 0);
  UnloadSkin();
  if (WizardForm.CurPageID=wpFinished) and (RunProgram.Checked) then
    Exec(ExpandConstant('{#AppRunningFile}'), '', '', SW_SHOWNORMAL, ewNoWait, ResultCode);

Не знаю на что Inno ругается: на Exec, или от версии самого Inno Ansi или Unicode... 
end; Хотя врятли...
 
Последнее редактирование:

vint56

Ветеран
Проверенный
RameR Вот пример
#define AppRunningFile "{app}\prototypef.exe"

[Setup]
AppName=[Prototype]
AppVerName=[Prototype]
AppVersion=1.0
DefaultDirName={pf}\Prototype
OutputDir=.
DefaultGroupName=Activision\Radical Entertainment\Prototype

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

[Files]
Source: prototypef.exe; DestDir: {app};

[CustomMessages]
RUS.RunProgram=Запустить {#SetupSetting("AppName")}

Код:
var
  RunProgram: TCheckBox;
  RunProgramLabel: TLabel;

procedure LabelOnClick(Sender: TObject);
begin
  case Sender of
  RunProgramLabel: begin RunProgram.Checked:= not RunProgram.Checked; end;
end;
end;

procedure DeinitializeSetup();
var ResultCode: Integer;
begin
  if (WizardForm.CurPageID=wpFinished) and (RunProgram.Checked) then
  Exec(ExpandConstant('{#AppRunningFile}'), '', '', SW_SHOWNORMAL, ewNoWait, ResultCode);
end;

procedure InitializeWizard();
begin
RunProgram:= TCheckBox.Create(WizardForm);
with RunProgram do
begin
  Parent:= WizardForm.FinishedPage;
  SetBounds(ScaleX(176), ScaleY(200), ScaleX(13), ScaleY(13))
  TabOrder:= 5;
  Checked:= True;
end;

RunProgramLabel:= TLabel.Create(WizardForm);
with RunProgramLabel do
begin
  Caption:=ExpandConstant('{cm:RunProgram}');
  SetBounds(ScaleX(196), ScaleY(200), ScaleX(150), ScaleY(13))
  Transparent := True;
  Parent:= WizardForm.FinishedPage;
  OnClick:= @LabelOnClick;
end;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
  RunProgram.Hide; RunProgramLabel.Hide;
if CurPageId = wpFinished then
begin
  RunProgram.Show; RunProgramLabel.Show;
end;
end;[/spoiler]
 
Последнее редактирование:

RameR

Новичок
Оказалось)) куда проще, не взял во внимание артикль Assassin's Creed III.exe!
Его Inno Setup и материл!)) Второй раз уже на эти грабли попадаюсь...
 

Tenebries

Мимокрокодил
Здравствуйте.

Подскажите пожалуйста что нужно дописать в скрипт чтобы при запуске инсталлятора он сверял реестер и если находило в нем значение (например: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 220440]) он запускался, а если не находило то выбивало сообщение...

И как сделать так, чтобы инсталлятор искал в реестре значение и по нему выставлял путь установки (например: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 220440],

Спасибо.
 

Winst@n

Участник
Проверенный
Tenebries,

function InitializeSetup(): Boolean;
begin
Result:= true;
if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 40990') then
MsgBox('Игра {#SetupSetting("AppName")} не найдена! Укажите путь к папке с игрой вручную!', mbinformation, mb_ok);
end;
 

ilzok17

Новичок
Помогите пожалуйста.Вопрос настолько примитивен,что о нём в инете даже никто не пишет.Что нужно прописать в скрипте чтобы после запуска инсталлятора происходила полностью "Тихая установка"(вообще без диалоговых окон)?Спасибо.
 

Tenebries

Мимокрокодил
Winst@n
Большое спасибо. Все работает... :)

И как сделать так, чтобы инсталлятор искал в реестре значение и по нему выставлял путь установки (например: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Uninstall\Steam App 220440], "InstallLocation"="D:\\Games\\steamapps\\common\\DmC Devil May Cry")?

Добавлено через 4 минуты
ilzok17
Кажется как-то так:

[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DisableDirPage=yes
DisableProgramGroupPage=yes
DisableReadyPage=yes
DisableFinishedPage=yes

[Files]
Source: "C:\My Program\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

Код:
procedure CurPageChanged(CurPageID: Integer);
begin
If CurPageID=wpWelcome then
begin
SendMessage(WizardForm.NEXTBUTTON.Handle, 513, 0, 0)
SendMessage(WizardForm.NEXTBUTTON.Handle, 514, 0, 0)
end;
end;[/QUOTE]
 

vint56

Ветеран
Проверенный
Tenebries
[Setup]
AppName=Assassin''s Creed
AppVerName=1.2
DefaultDirName={code:GetInstallDir}

;InstallLocation
;InstallPath
;InstallDir

Код:
//Function GetInstallDir( AppID: String ): String; var dir: String;
//begin
//if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0E64B098-8018-4256-BA23-C316A43AD9B0}', 'InstallLocation', dir) then
//RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0E64B098-8018-4256-BA23-C316A43AD9B0}', 'InstallLocation', dir);
//Result:= dir;
//end;
//
//function InitializeSetup(): Boolean;
//begin
//Result:= True;
//if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0E64B098-8018-4256-BA23-C316A43AD9B0}') then
//begin
//if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0E64B098-8018-4256-BA23-C316A43AD9B0}') then
//begin
//MsgBox('{#SetupSetting("AppName")} не найдена!', mberror, mb_ok);
//Result:=False;
//end;
//end;
//end;

Function GetInstallDir( AppID: String ): String; var dir: String;
begin
if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 220440', 'InstallLocation', dir) then
RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 220440}', 'InstallLocation', dir);
Result:= dir;
end;

function InitializeSetup(): Boolean;
begin
Result:= True;
if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 220440') then
begin
if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 220440') then
begin
MsgBox('{#SetupSetting("AppName")} не найдена!', mberror, mb_ok);
Result:=False;
end;
end;
end;[/SPOILER]
 

vint56

Ветеран
Проверенный
Tenebries
[Setup]: DirExistsWarning
Возможные значения:
auto, yes, или no
Значение по умолчанию:
auto
Описание:
При значении auto инсталлятор выдаст сообщение "Папка: … уже существует. Вы хотите продолжить установку в эту папку?" ("The directory ... already exists. Would you like to install to that directory anyway?"), если пользователь укажет для установки существующую папку, за исключением, если это папка с ранней версией программы и только когда UsePreviousAppDir=yes.
При значении yes инсталлятор всегда будет выдавать сообщение "Directory Exists" при попытке установки в существующую папку.
При значении no инсталлятор не будет выдавать сообщение "Directory Exists".
 

Tenebries

Мимокрокодил
bugron
Спасибо. :)

vint56
Начинал ее читать, но очень скоро надоела... :)
Спасибо.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху