Создание установщика из любых файлов в Inno Setup

02.06.24

Разработка - Инструментарий разработчика

Рассмотрим способ создания Windows-установщика из любых файлов при помощи простого, но мощного инструментария Inno Setup.

Установщик - удобная штука, которая часто оказывается даже более предпочтительным вариантом для компактного переноса данных, чем zip-архив, и абсолютно превалирующим в тех случаях, когда подразумевается распространение своего продукта вовне.

В этой статье процесс создания установщика я буду рассматривать с оглядкой на OneScript: в качестве примера выступит установщик OInt CLI, а отдельное внимание будет уделено особенностям установки именно CLI приложений - в принципе единственного на сегодняшний день адекватного варианта приложения на OS. Потому что выпускать CLI приложение без установщика или даже, как это часто бывает, без exe файла в релизе это не круто - не делайте так

Работать мы будем с программным пакетом Inno Setup - с его рассмотрения и начнем

 

 

Inno Setup - это система создания Windows-установщиков с открытым исходным кодом. Она написана на Pascal и Pascal же (с оговорками) используется в ней для описания установочных скриптов. В этих скриптах можно:

 

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

 

Все это делается либо просто в текстовом редакторе, либо в редакторе скриптов Inno Setup Compiler, где есть кнопки для быстрой сборки и даже отладчик с точками останова

 

Скачать Inno Setup: https://jrsoftware.org/isdl.php

 

Сам скрипт делится на секции, по которым мы сейчас и пройдемся

 

Начало документа

 

До начала именных блоков, в iss-скрипте мы можем определить глобальные переменные. Это удобно по отношению к тем данным, которые могут неоднократно использоваться в процессе описания установщика

 

Делается это при помощи ключевого слова #define:

#define MyAppName "OInt"
#define MyAppVersion "1.9.0"
#define MyAppPublisher "bayselonarrend"
#define MyAppURL "https://github.com/Bayselonarrend/OpenIntegrations"
#define MyAppExeName "oint.exe"
#define OtherFiles "D:\GD"
#define Repo "D:\Repos\OpenIntegrations"

 

В дальнейшем мы можем использовать эти переменные через конструкцию {#ИмяПеременной}

 

Блок Setup

 

В блоке Setup определяются основные настройки нашего установщика. Делается это через присвоение значений параметрам-переменным, коих очень много, но для себя я пришел к определенному их набору, который скорее всего подойдет для решения большинства задач. Вот он:

 

[Setup]
DisableWelcomePage=no
WizardImageFile={#Repo}\Media\WizardImage.bmp
AppId={{E1D44D44-2C84-4112-80AA-2DC406D85A11}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
LicenseFile={#Repo}\LICENSE
OutputDir="{#OtherFiles}\Релизы\{#MyAppVersion}"
Compression=lzma
SolidCompression=yes
WizardStyle=modern
OutputBaseFilename=oint_{#MyAppVersion}_installer

 

Рассмотри всё по-порядку:
 

  • DisableWelcomePage - параметр, отвечающий за показ страницы приветствия. Так как на этой странице отображается некоторая информация о приложении, а еще там можно показать какую-нибудь красивую картинку, было решено её включить


     
  • WizardImageFile - картинка формата bmp, которая отображается сбоку на странице приветствия и завершения установки. Добавляет индивидуальность установщику - это важно. Подходящие размеры для картинки это 410x797, 355x700, 328x604. Минимальный размер 164x314
     
  • AppId - это UID, который необходим для определения связи между разными установщиками и установленной программой. Например, если при выходе новой версии вашей программы вы заново скомпилируете установщик, то при совпадающих AppId этот установщик перезапишет данные прошлой версии, а если нет - установит её как абсолютно новый продукт. В частности это видно в разделе "Программы и компоненты" Windows
     
  • AppName - имя приложения, которое будет отображаться в установщике, а также в меню Пуск после установки
     
  • AppVersion - версия программы. Будет видна в установщике, а также в разделе программ и компонентов

     
  • AppVerName - вариант отображения в тех местах, где имя и версия находятся в одной строке. Необязательный пункт
     
  • AppPublisher - информация (в частности имя) об издателе приложения. Если не указать - будет вылазить окно с красным щитом о недостоверности издателя
     
  • AppPublisherURLAppSupportURLAppUpdatesURL - различные URL издателя. Их также можно найти в программах и компонентах 

     
  • DefaultDirName - путь, который будет отображаться по умолчанию в строке выбора места установки. {autopf} здесь - служебная константа, автоматически определяющая путь к Program Files
     
  • DefaultGroupName - имя, которое будет использовано для папки программы в меню Пуск по умолчанию
     
  • DisableProgramGroupPage - признак отображения страницы выбора имени группы. Мне функционал выбора имени папки программы в меню Пуск кажется излишним, но это субъективно. При отключенной странице будет просто использован DefaultGroupName
     
  • LicenseFile - путь к текстовому файлу лицензионного соглашения. Его содержимое будет показано перед началом установки


     
  • OutputDir - каталог для сохранения готового установщика
     
  • Compression - способ сжатия файлов в установщике
     
  • SolidCompression - уменьшает размер установщика, но при этом и скорость распаковки
     
  • WizardStyle - определяет стиль установщика: modern (как на скриншотах) или classic. Хотя разница, на самом деле, не велика - серый цвет и чуть меньшее окно


     
  • OutputBaseFilename - имя выходного файла установщика

 

Блок Languages

 

Тут все просто: язык установщика по умолчанию - английский. Если же мы хотим, чтобы наш установщик был на русском, то необходимо добавить следующий блок:

 

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

 

Языков можно добавлять несколько. Их список определяется файлам в папке Languages каталога программы. Английский язык добавляется как Default.isl

 

[Languages]
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "english"; MessagesFile: "compiler:Default.isl"

 

 

 

Блок Files

 

Блок Files определяет список файлов, которые будут использованы для создания установщика. Каждый файл может быть описан полями Source - путь к файлу на диске, DesDir - путь, по которому файл будет распакован при установке и Flags - различные отметки об необходимости особой обработки файла

[Files]
Source: "C:\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\start.bat"; DestDir: "{app}"


В качестве DestDir тут выступает {app} - путь установки приложения, выбранный пользователем. Если мы хотим, чтобы файл распаковался в какую-нибудь подпапку, то можно отталкиваться от него: {app}/Папка2. Также доступны абсолютные пути и другие переменные

Флаг ignoreversion у исполняемого файла означает, что при установке поверх прошлой версии файл будет перезаписан в любом случае, даже если вы сначала установите более новую версию программы, а после - более старую

 

Блок Tasks

 

Блок Tasks позволяет выводить чекбоксы пользователю перед началом установки. Например, вопрос о создании ярлыка на рабочем столе

 

[Tasks]
Name: desktopicon; Description: "Создать ярлык на рабочем столе";

 

 

Далее мы можем использовать сделанный пользователем выбор в качестве условия для выполнения каких-либо действий


Блок Icons

 

Блок Icons отвечает за создание иконок, в частности на рабочем столе и в меню пуск

 

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\start.bat"; IconFilename: "C:\Media\ex.ico"
Name: "{userdesktop}\{#MyAppName}"; Filename: "{app}\start.bat"; IconFilename: "C:\Media\ex.ico"; Tasks: desktopicon
Name: "{group}\Удалить OInt"; Filename: "{uninstallexe}"; IconFilename: "C:\Media\wizard.ico"
Name: "{group}\Web-документация"; Filename: "https://www.openintegrations.dev/" 

 

Что мы здесь видим?

  • В поле Name указывается целевой путь для размещения иконки с её именем в конце. Здесь он начинается либо с {group} - папка программы в меню Пуск, либо с {userdesktop} - переменной, хранящей путь к рабочему столу пользователя
     
  • В Filename определяется путь к файлу или URL, на который буде ссылаться ярлык. Пути определяются как DestDir в Files, а URL должен иметь протокол и www.
     
  • Для каждого ярлыка можно установить свой файл иконки при помощи параметра IconFilename. Иконки должны быть в формате ico


     
  • Параметр Tasks определяет проверки на чекбоксы, о которых мы говорили в прошлом блоке. Здесь для второй иконки определено Tasks: desktopicon - по имени таски, которую мы добавили для чекбокса создания ярлыка на рабочем столе
     

 

Блок Run

 

Блок Run отвечает за запуск команд в разные моменты работы нашего установщика. Нас этот блок интересует как способ создать предложение о запуске чего либо по завершении установки

 

[Run]
Filename: "{cmd}"; Parameters: "/k ""cd ""{app}"" && {#MyAppExeName}"""; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall
Filename: "https://openintegrations.dev/docs/Nachalo-raboty/Rabota-s-CLI-versiei"; Flags: shellexec runasoriginaluser postinstall; Description: "Посетить страницу документации openintegrations.dev"

 

Также, как и в случае с иконками, мы можем указывать в качестве целевого объекта файлы и URL, однако, помимо этого, нам еще становятся доступны консольные команды

В первой строке идет запуск одной из них: как я уже говорил, наш текущий пример нацелен на запуск CLI приложения. Для того, чтобы окно командной строки не закрылось тут же после запуска, нам необходимо сначала запустить cmd, а только потом, внутри него, командой запустить само приложение. На данный момент еще не будет прописан Path, так что мы сначала делаем cd в каталог приложения, а потом вызываем exe

Далее в Description определяется действие по замене заголовка окна консоли на имя нашей программы. Флаги nowait и postinstall означают, что при наличии нескольких выбранных пользователем действий после установки, они выполнятся без ожидания завершения работы текущего: у нас это будет "Посетить страницу документации", так вот, если не указать postinstall, то страница не откроется, пока не будет закрыт cmd с нашей программой

Второе действие - с переходом по ссылке на страницу документации - во многом схоже, только тут еще добавляются флаги shellexec - замена вызову команды через cmd, если сам cmd не нужен, а также runasoriginaluser - выполнение команды от имени текущего пользователя

 

 


Блоки Registry и Code

 

Несмотря на всю гибкость блока Code - буквально компилятора, который способен выполнять код на Pascal, я не нашел особо другого его применения, кроме как для написания функции проверки данных в реестре, по-этому объединил их в один пункт

Registry нужен нам для добавления каталога программы в Path, что позволит вызывать наше CLI приложение из любого места просто по имени. Если у вас не CLI приложение, то данный пункт можно пропустить.

Способ добавления Path через Registry - не самый простой, но зато самый надежный. Дело в том, что при выполнении этого действия через командную строку, есть вероятность переполнения Path - при прямом доступе он ограничен по длине, что может привести не только к некорректному добавлению вашего пути, но и к урезанию уже существующих там каталогов, если они были забиты через реестр

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

 

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
    ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}"; \
    Check: NeedsAddPath(ExpandConstant('{app}'))

 

Тут мы обращаемся к HKLM в переменные CurrentControlSet и перезаписываем Path, соединяя {olddata} - прошлое значение переменной и {app} - каталог нашего приложения через точку с запятой. Однако делается это только после прохождения Check - функции, описанной в блоке Code

 

[Code]

function NeedsAddPath(Param: string): boolean;
var
  OrigPath: string;
  Element: string;
begin
  if not RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'Path', OrigPath)
  then begin
    Result := True;
    exit;
  end;
  Element:= ';' + Param + ';';
  Result := Pos(Element, ';' + OrigPath + ';') = 0;
end;    

 

Эта функция - NeedsAddPath - проверяет Path на наличие добавляемого пути. Если данного пути в Path нет, то возвращается Истина и путь добавляется. В противном случае, если путь уже есть в переменной, то Check не проходит и второй раз наш каталог в Path не попадет. Это позволяет не плодить копии пути к папке приложения при обновлении программы или если программы была удалена и установлена заново

 

В заключение

 

Установщик - отличный способ распространения файлов, а создать его - разве что чуть сложнее, чем архив. Сформированный один раз .iss скрипт можно использовать в дальнейшем сколько угодно раз, в том числе и из командной строки
 

"C:\Program Files (x86)\Inno Setup 6\Compil32.exe" /cc "C:\myscript.iss"

 

Пример скрипта из статьи можно найти в репозитории Открытого пакета интеграций. Там же можно посмотреть и готовый установщик

 

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

 

 

 Мой GitHub:     https://gitub.com/Bayselonarrend 
 Лицензия MIT:   https://mit-license.org

Inno Setup установка установщик install installer инсталлер

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    156793    849    398    

855

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP и т.д.). Поддерживаются управляемые и обычные формы. Может выполнять свертку сразу нескольких баз данных и выполнять их автоматически без непосредственного участия пользователя.

8400 руб.

20.08.2024    6504    46    22    

57

Инструментарий разработчика Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Инструмент для написания и отладки кода в режиме «1С:Предприятие». Представляет собой консоль кода с возможностью пошаговой отладки, просмотра значений переменных любых типов, использования процедур и функций, просмотра стека вызовов, вычисления произвольных выражений на встроенном языке в контексте точки останова, синтаксического контроля и остановки по ошибке. В консоли используется удобный редактор кода с подсветкой, контекстной подсказкой, возможностью вызова конструкторов запроса и форматной строки.

9360 руб.

17.05.2024    22525    66    43    

114

Инструменты администратора БД Инструментарий разработчика Роли и права Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

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

10000 руб.

10.11.2023    10068    36    19    

61

Пакетная печать Печатные формы Инструментарий разработчика Программист Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:Конвертация данных 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

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

22200 руб.

06.10.2023    15024    35    7    

70

SALE! %

Инструментарий разработчика Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

4800 3840 руб.

14.01.2013    186990    1134    0    

907

Инструментарий разработчика Программист 8.3.14 1С:Конвертация данных Россия Платные (руб)

Расширение для конфигурации “Конвертация данных 3”. Добавляет подсветку синтаксиса, детальную контекстную подсказку, глобальный поиск по коду.

15000 руб.

07.10.2021    17103    6    32    

42

Инструментарий разработчика Программист Платформа 1С v8.3 Платформа 1C v8.2 Платформа 1С v8.1 Конфигурации 1cv8 Платные (руб)

Программист - это человек, непрерывно принимающий решения. Написание кода не является процессом принятия решения - это всего лишь трансляция ваших желаний. Если вас периодически тяготит написание сотен строк кода ради решения задач, то прошу обратить внимание. Данный продукт позволит существенно сократить время на рутинные операции при разработке. За счет библиотечной реализации сокращается объём кода, а его читаемость повышается. К библиотеке прилагается документация API и шаблоны кода для наиболее популярных методов.

4200 руб.

16.04.2021    15361    6    10    

18
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Xershi 1550 02.06.24 22:56 Сейчас в теме
Старницу, улыбнуло+))
bayselonarrend; +1 Ответить
2. bayselonarrend 2085 03.06.24 07:09 Сейчас в теме
(1)Самое забавное, что это даже опечатка не в статье, а в установщике) Спасибо
3. 300_po_vstrechke 2102 03.06.24 10:08 Сейчас в теме
Потому что выпускать CLI приложение без установщика или даже, как это часто бывает, без exe файла в релизе это не круто - не делайте так


По-моему, самый сладкий софт лежит в исходниках.
Три этапа становления современного программиста:
1. Зашёл на гатхаб - ничего не понятно, но очень интересно.
2. Залипаешь на гитхабе в место вечернего сериальчика и ютуба.
3. Научился собирать файлы из исходников и почувствовал что схватил жизнь за бороду.
5. bayselonarrend 2085 03.06.24 11:01 Сейчас в теме
(3)Спорно. Если на gh лежат исходники на ЯП, которого я не знаю, а мне просто нужен прикладной софт для использования, то последнее, чем я хотел бы заниматься, это вникать в сборку и поднимать окружение.

ИМХО мне лично очень не нравится, когда я вижу репозиторий, который вроде хранит сорцы готового продукта, но не имеет ни человеческого ридмика, ни оформленных релизов, ни сайта. Сразу чувствуется какое-то наплевательское отношение
7. 300_po_vstrechke 2102 03.06.24 11:18 Сейчас в теме
(5)
ИМХО мне лично очень не нравится, когда я вижу репозиторий, который вроде хранит сорцы готового продукта, но не имеет ни человеческого ридмика, ни оформленных релизов, ни сайта. Сразу чувствуется какое-то наплевательское отношение


Это к тому же вопросу, например, почему люди до сих пор используют консольные приложения? Элементарно же, форму запилить и кнопок на неё сыпануть. Зачем писать -h и разбираться в этих гадских командах? Наверное потому, что хочется чувствовать себя творцом, а не потребителем.
8. bayselonarrend 2085 03.06.24 11:27 Сейчас в теме
Элементарно же, форму запилить и кнопок на неё сыпануть


Смысл использования консольных приложений гораздо банальнее, чем "чувство творца": если мне надо при помощи программы автоматизировать какую-нибудь работу, то с GUI я это никак не сделаю. Вызов консольного приложения можно и в bat/sh подтянуть, и как службу, и в коде на другом языке вызвать, если уже совсем приперло. После чего через ">" сделать вывод текстовый файлик и проанализировать результат потом
4. artbear 1563 03.06.24 10:19 Сейчас в теме
Она написана на Pascal и Pascal же (с оговорками) используется в ней для описания установочных скриптов.


внезапно, Паскаль был у меня первым языком программирования, книжка Вирта + отжатый у учителя PDP-11 в компьютерном классе школы
Prometeus2011; +1 Ответить
6. bayselonarrend 2085 03.06.24 11:02 Сейчас в теме
(4) Так Inno Setup в 97-м вышел)
9. dsdred 3566 03.06.24 12:33 Сейчас в теме
(4)Я думал все с Basic начинали ))
Паскаль я уже после него щупал.
10. bayselonarrend 2085 03.06.24 12:35 Сейчас в теме
(9)Basic мы и сейчас все щупаем)
klonbest; 300_po_vstrechke; dsdred; +3 Ответить
11. gaglo 05.06.24 09:47 Сейчас в теме
(9) Ну живы еще и те, кто начинал с Фортрана... Я, например. Бэйсик щупал только в виде VBA в Excel. Ну в этом случае вариантов не было. Паскаль даже и щупать не стал, ибо тогда одновременно Turbo Pascal и Turbo C имелись... Выбрал сразу Turbo C, не пожалел ни разу.
Оставьте свое сообщение