Inno Setup 介绍及打包配置
Inno Setup是一个免费的Windows程序安装程序, 由乔丹·罗素和马蒂恩·兰于1997年首次推出,如今在功能集和稳定性方面可与许多商业安装程序相媲美甚至超越。Inno Setup用Delphi写成,支持pascal脚本,其官方网站同时也提供源程序免费下载。它虽不能与Installshield这类恐龙级的安装制作软件相比,但也当之无愧算是后起之秀。
Inno Setup下载地址:https://jrsoftware.org/isdl.php
Inno Setup文档:https://jrsoftware.org/ishelp/
主要特点:
- 支持自2006年以来的每个Windows版本。
- 广泛支持在64位版本的Windows上安装64位应用程序。x64、ARM64和安腾架构均受支持。
- 对管理和非管理安装安装的广泛支持。
- 支持创建单个 EXE 来安装程序,以便于在线分发。还支持磁盘跨越。
- 可调整大小的标准视窗向导界面。
- 可自定义的设置类型,例如完整、最小、自定义。
- 完整的卸载功能。
- 文件安装:包括对“deflate”、bzip2和7-Zip LZMA/LZMA2 文件压缩的集成支持。安装程序能够比较文件版本信息、替换正在使用的文件、使用共享文件计数、注册 DLL/OCX 和类型库以及安装字体。
- 在任何地方创建快捷方式,包括在“开始”菜单和桌面上。
- 创建注册表和 .INI条目。
- 在安装之前、期间或之后运行其他程序。
- 支持多语言安装,包括从右向左语言支持。
- 支持密码保护和加密安装。
- 支持数字签名安装和卸载,包括双重签名 (SHA1 和 SHA256)。
- 静默安装和静默卸载。
- Unicode安装。
- 用于高级编译时自定义的集成预处理器选项。
- 集成的 Pascal 脚本引擎选项,用于高级运行时安装和卸载自定义。
- 完整的源代码可从 GitHub 获得[外部链接]。
- 占用空间小:开销仅为约 1.5 mB,包含所有功能。
- 所有功能都完整记录。
- 被Microsoft Visual Studio Code 和 Embarcardero Delphi使用。
它真的是免费的,即使是商业用途吗?
是的,即使在部署商业应用程序时,也可以完全免费使用它。
从Inno Setup下载最新版本,本文使用的版本为:innosetup-6.2.1.exe
下载安装完毕后,在安装目录\Inno Setup 6\Examples下,有官方提供的一些Example示例,可以参考并编写自己的打包脚本。如下图示:
可以根据AllPagesExample.iss示例,了解所有安装页面,并组织自己的安装流程页面。
Inno Setup打包配置可参考以下Demo:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppId "business-app-release"
#define MyAppName "商务云平台"
#define MyAppVersion "V1.1.5"
#define MyAppPublisher "AppBusinessCloud,Inc."
#define MyAppURL ""
#define MyAppExeName "商务云平台.exe"
[Setup]
AppId={#MyAppId}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName}{#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName=business
DisableProgramGroupPage=yes
WizardStyle=modern
OutputBaseFilename=business
Compression=lzma
SolidCompression=yes
SetupLogging=yes
;OutputDir=
DisableWelcomePage=no
LicenseFile=install/License.txt
SetupIconFile=D:\business\business-install\install\favicon.ico
AppCopyright=Copyright (C) 2022 AppBusinessCloud, Inc.
[Languages]
Name: "cn"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
[Files]
Source: "D:\business\business-install\install\*"; DestDir:"{app}";Flags: ignoreversion recursesubdirs createallsubdirs
[Icons]
Name: "{commondesktop}\{#MyAppName}"; IconFilename: "{app}\favicon.ico"
[INI]
Filename: "{app}\business.ini"; Section:"default"; Key: "app"; String: "{app}"
Filename: "{app}\business.ini"; Section:"default"; Key: "tenantName"; String: "{code:GetBusinessInfo|name}"
Filename: "{app}\business.ini"; Section:"default"; Key: "tenantCode"; String: "{code:GetBusinessInfo|code}"
[Code]
var
CustomInputPage: TInputQueryWizardPage;
tenantName, tenantCode, serialNumber: String;
procedure WriteFixmedinsInfoFile;
var
fileName,tempStr:String;
svArray: TArrayOfString;
nLines,i:Integer;
begin
Log('WriteFixmedinsInfoFile...');
fileName := ExpandConstant('{app}\sql\org.sql');
LoadStringsFromFile(fileName, svArray);
nLines := GetArrayLength(svArray);
for i := 0 to nLines - 1 do
begin
tempStr := svArray[i];
Log(tempStr);
if (Pos('#{tenantName}', tempStr) > 0) then
begin
StringChangeEx(svArray[i], '#{tenantName}', tenantName, True); //将[tenantName]占位符替换为tenantName对应值
end;
if (Pos('#{tenantCode}', tempStr) > 0) then
begin
StringChangeEx(svArray[i], '#{tenantCode}', tenantCode, True); //将[tenantCode]占位符替换为tenantCode对应值
end;
if (Pos('#{serialNumber}', tempStr) > 0) then
begin
StringChangeEx(svArray[i], '#{serialNumber}', serialNumber, True); //将[serialNumber]占位符替换为serialNumber对应值
end;
end;
SaveStringsToUTF8File(fileName, svArray, false);
end;
var SerialNumberMemo: TNewMemo;
procedure InitializeWizard;
var
Index: Integer;
CustomEdit: TCustomEdit;
begin
Log('InitializeWizard...');
// Create the page
CustomInputPage := CreateInputQueryPage(wpLicense,
'租户信息', '提示信息:租户名称和租户编码请联系商务获取!',
'请填写您的租户名称和租户编码信息');
// Add items (False means it's not a password edit)
CustomInputPage.Add('&租户名称:', False);
CustomInputPage.Add('&租户编码:', False);
Index := CustomInputPage.Add('&序列号:', False);
CustomEdit := CustomInputPage.Edits[Index];
SerialNumberMemo := TNewMemo.Create(WizardForm);
SerialNumberMemo.Parent := CustomEdit.Parent;
SerialNumberMemo.SetBounds(CustomEdit.Left, CustomEdit.Top, CustomEdit.Width, ScaleY(70));
CustomEdit.Visible := False;
CustomInputPage.PromptLabels[Index].FocusControl := SerialNumberMemo;
// Set initial values (optional)
CustomInputPage.Values[0] := ExpandConstant('');
CustomInputPage.Values[1] := ExpandConstant('');
CustomInputPage.Values[3] := ExpandConstant('');
end;
function GetBusinessInfo(Param: String): String;
begin
Result := tenantName;
if Param = 'name' then begin
Result := tenantName;
WriteFixmedinsInfoFile;
end else if Param = 'code' then begin
Result := tenantCode;
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
{ Validate certain pages before allowing the user to proceed }
Result :=True;
if CurPageID = CustomInputPage.ID then begin
if CustomInputPage.Values[0] = '' then begin
MsgBox('租户名称不能为空!', mbError, MB_OK);
Result := False;
end else if CustomInputPage.Values[1] = '' then begin
MsgBox('租户编码不能为空!', mbError, MB_OK);
Result := False;
end else if SerialNumberMemo.Text = '' then begin
MsgBox('序列号不能为空!', mbError, MB_OK);
Result := False;
end
// 非空格式校验
else if CustomInputPage.Values[1] <> '' then begin
if (Length(CustomInputPage.Values[1]) < 12) then
begin
MsgBox('租户格式编码错误!', mbError, MB_OK);
Result := False;
end;
end;
// Read values into variables
tenantName := CustomInputPage.Values[0];
tenantCode := CustomInputPage.Values[1];
serialNumber := SerialNumberMemo.Text;
end;
end;
[Run]
Filename: "{app}\install.bat"
[UninstallRun]
RunOnceId: "SmapleUnInstallService"; Filename: "{app}\uninstall.bat"
更多Inno Setup使用参见官方帮助文档:Inno Setup Help