Inno Setup实战:从零开始打造专业Windows安装包
作为一个经常给 Windows 软件做安装包的人,我这些年用过的打包工具不少,但真正让我觉得“够用、不折腾、还能折腾”的,还是 Inno Setup Compiler。这玩意儿免费、轻量、功能却不输商业工具,而且它的脚本系统一旦吃透,几乎能实现你对安装程序的任何“奇怪想法”。
这篇教程我会从“完全没接触过”的状态讲起,带你一步步走通从下载工具、编写脚本、编译打包,到处理卸载残留、签名发布、静默安装的完整流程。中间会穿插我实际踩过的坑和总结的小技巧,希望能帮你少走一些弯路。它适合刚入门的开发者、需要快速交付安装包的项目负责人,以及想进阶了解安装包定制逻辑的工程师。
1. 为什么是 Inno Setup:写在动手之前的选型思考
市面上能打包 Windows 软件的工具不少,但多数要么收费,要么太重,要么就是封装成“黑盒子”,想改点东西无从下手。Inno Setup 的优势在于它的核心逻辑是“脚本驱动”,你告诉它“把什么文件放到哪里、创建哪些快捷方式、写哪些注册表”,它就严格照做,整个过程透明可控。
1.1 它到底解决了什么问题
先说一个常见的痛点:你的程序编译完,往往是一大堆文件,有 exe、dll、配置文件,还有 data 文件夹。直接发给用户,用户要么不知道放哪,要么把文件放得乱七八糟,最后跑不起来,还得回头找你。安装包的价值就在这里——它把散落的文件组织成一个标准化的安装流程,自带默认目录、开始菜单快捷方式、卸载入口,让用户像装微信、QQ 一样装你的软件。
Inno Setup 生成的安装包最直观的特点就是“干净”。它安装后自带卸载程序(Uninstall.exe),而且卸载时能把快捷方式、注册表项、安装的文件一并清掉,不会在系统里留一堆垃圾。这点在 Windows 上尤其重要,因为用户的系统环境千奇百怪,一个装不干净、卸不干净的软件会很快消耗掉用户的信任。
1.2 和同类工具对比,为什么要选它
我以前也试过其他方案,比如 NSIS(Nullsoft Scriptable Install System)。NSIS 也很强,但它的语法风格偏底层,写起来像是“汇编语言”式的安装逻辑,对新手不算友好,调试起来也不直观。还用过一些商业工具,界面华丽,但价格不低,而且很多功能你根本用不到。
Inno Setup 的定位恰好卡在中间:它提供了所见即所得的脚本编译环境,同时有完整的 Pascal 脚本接口供深度定制。对绝大多数 Windows 桌面软件发布场景来说,Inno Setup 的学习曲线最平缓,功能覆盖度也最高。它支持各种 Windows 版本、多语言安装界面、安装时修改注册表、运行自定义命令、下载依赖组件(配合代码实现)、创建多磁盘安装包等等,足够覆盖一个软件从初创到成熟的全过程。
一句话:如果你不想为“用不上的功能”付费,又不想为“复杂到劝退的脚本”头疼,Inno Setup 是平衡得最好的那个选择。
2. 环境准备与第一个安装包
任何工具都要先跑通再说,所以这一部分先不讲复杂逻辑,专注带你把 Inno Setup 装好,并用向导模式生成第一个能用的安装包。
2.1 下载安装 Inno Setup 编译器
Inno Setup 的官方网站是jrsoftware.org,主页上会提供当前的最新版本下载链接。这里有个细节:安装文件分“单纯的编译器”和“附带 Unicode 支持”的版本。现在 Windows 软件基本都该用 Unicode 版本,它能正确处理中文等多语言路径和文件名,避免乱码问题,所以下载时认准带有 “Unicode” 标识的安装包即可,文件体积很小,通常只有几 MB。
安装过程没什么特别之处,一路 Next 就行。装完后你会在开始菜单看到“Inno Setup Compiler”程序组,里面有两个重要的入口:一个是主程序“Inno Setup Compiler”(编译器界面),另一个是“Inno Setup Documentation”(官方文档)。
提示:别跳过官方文档。它虽然长得朴素,但内容极其完整,包含了所有段位、参数和 Pascal 脚本函数的说明,是排查问题时的第一手参考资料。
2.2 五分钟向导:从零做出能用的安装包
第一次打开 Inno Setup Compiler,它会弹出一个欢迎界面,里面有几个选项。选第一个“Create a new script file using the Script Wizard”,也就是使用向导创建脚本,后面它会一步步问你问题,流程大概是这样:
- Application Information 页面:填写应用名称、版本号、发布者名称、网址。这些信息会写入安装包属性和“卸载”程序的“程序和功能”列表里。应用名称建议填正式的显示名,比如“MyTool”,不要带版本号,因为版本号有单独字段。
- Application Folder 页面:设置默认安装目录。默认值一般是“{pf}\MyTool”({pf} 是 Program Files 的常量),如果你是给绿色工具打包,也可以改成“{autopf}”或自定义路径。注意“Allow user to change the application folder”这个选项,如果你希望安装时可以选目录,就勾上。
- Application Files 页面:选择要打包的文件和主程序 exe。这里有个“Add file(s)...”按钮,支持多选,也可以选整个文件夹(Add folder...)。主程序 exe 是用来在安装完成后自动运行、创建启动项或者关联文件类型的核心文件。
- Application Shortcuts 页面:选择创建哪些快捷方式,比如“Start Menu entry”(开始菜单)和“Allow creation of a desktop shortcut”(桌面快捷方式)。这些会在安装时自动创建,卸载时自动删除。
- Application Documentation 页面:可选添加说明文件,比如 readme.txt、许可协议 license.txt。如果你有最终用户许可协议(EULA),这里可以指定一个 rtf 或 txt 文本。
- Setup Install Mode 页面:问你是否需要“让所有用户都可用”还是“仅当前用户”。一般建议选“Install for all users”,因为它会默认写入 Program Files,并在开始菜单创建公共快捷方式,更符合常规软件的行为。
- Setup Languages 页面:选择安装界面语言。如果选择简体中文,安装向导界面就是中文的。Inno Setup 会自动带上官方语言文件,这里选中文就能让安装画面变中文,不需要额外汉化。
- Compiler Settings 页面:设置输出目录和安装包 exe 的文件名,以及是否使用自定义图标。图标建议用 ico 格式,尺寸 48x48 或 256x256 都行。
- Inno Setup Preprocessor 页面:询问是否启用预处理器(ISPP)。一般保持默认勾选即可,ISPP 能让你在脚本里使用变量、条件编译、文件通配符展开等功能,属于高级利器,后续会讲到。
完成向导后,它会生成一个 .iss 脚本文件,并自动打开在编辑器里。此时点击工具栏上的“Run”按钮(或按 F9),Inno Setup 就会开始编译,并自动运行生成的安装包。如果你只想编译不运行,点“Compile”(或按 Ctrl+F9)。
至此,花五分钟的时间,你已经拥有了一个“能装、能卸、带快捷方式”的 Windows 安装包。接下来要进阶的,就是理解这套脚本到底在说什么。
3. 脚本语言详解:把安装过程讲清楚
Inno Setup 的脚本文件 .iss 本质上是一个文本文件,采用“段(Section)”结构组织。每一段用方括号包裹的段名开头,下面跟着一行一行的参数或条目。这种设计非常清晰,读起来就像在读一份安装步骤说明书。
3.1 脚本的基本结构与关键段位
让我们先看一个最小可用的 .iss 脚本骨架:
[Setup]
AppName=MyTool
AppVersion=1.0
DefaultDirName={autopf}\MyTool
OutputBaseFilename=MyToolSetup
Compression=lzma2
SolidCompression=yes
[Files]
Source: "D:\release\mytool.exe"; DestDir: "{app}"
Source: "D:\release\config.ini"; DestDir: "{app}"
[Icons]
Name: "{group}\MyTool"; Filename: "{app}\mytool.exe"
Name: "{commondesktop}\MyTool"; Filename: "{app}\mytool.exe"
这里几段各司其职:
- [Setup] 段是全局配置区。它控制安装包的元数据,比如 AppName(应用显示名)、AppVersion(版本号)、DefaultDirName(默认安装目录)、OutputBaseFilename(输出的安装包文件名)、Compression(压缩方式)等。Compression 常用的是 lzma2 或 lzma,lzma 压缩率高但编译慢一点,lzma2 在压缩率和速度之间平衡更好。SolidCompression 如果设为 yes,会把所有文件作为一个整体压缩,体积更小,但是如果你想把某个文件单独提取出来做特殊处理,就不好办了。
-
[Files]
段是核心段位,决定“哪些文件、装到哪里”。Source 是源文件路径,DestDir 是目标目录。Inno Setup 支持通配符,比如
Source: "D:\release\*"; DestDir: "{app}"会把目录下所有文件都打包。也支持Excludes: "*.tmp"排除特定文件,Flags: recursesubdirs递归子目录。 -
[Icons]
段控制快捷方式。Name 指快捷方式的完整路径,Filename 是它指向的目标程序。
{group}是“开始菜单程序组”路径(在 [Setup] 段还可以用 DefaultGroupName 指定组名),{commondesktop}是“公共桌面”路径,也就是所有用户的桌面。 -
[Registry]
段,负责写注册表。格式是
Root: {constant}; Subkey: "..."; ValueType: string; ValueData: "..."。可以用来写文件关联、写启动项、写设置项。 -
[Run]
段,负责在安装完成后运行程序或命令。常见用法是安装完启动主程序,或者调用某些 DLL、执行某些配置命令。格式为
Filename: "{app}\mytool.exe"; Description: "Launch MyTool"; Flags: nowait postinstall skipifsilent。 - [UninstallDelete] 和 [UninstallRun] 段则负责卸载时的清理,可以删除指定的文件、文件夹、注册表键值,也可以执行卸载命令。Inno Setup 默认会删除安装目录下的文件,但是如果你在安装时写了额外的注册表或生成了不属于安装目录的配置,就需要在这里配置清理。
这些段位就是整个安装脚本的骨架。脑子里带着“装什么到哪、建什么快捷方式、写什么注册表、装完跑什么”这四条主线去写脚本,思路就会非常清晰。
3.2 段位详解:Files、Icons、Registry、Run
Files 段的参数延展
Files 段最常用的一组参数是:Source、DestDir、Flags、Permissions、Attribs。其中 CopiesMode 可以设定为默认的“复制文件”,或者设为“创建快捷方式(symlink)”,这个在装便携工具时偶尔能用到。Flags 参数非常丰富,常用的有这几个:
-
onlyifdoesntexist:若目标文件已存在则不覆盖。 -
ignoreversion:忽略目标文件已有的版本号问题,强制覆盖。安装新版本时如果提示文件被占用或者版本冲突,可以加这个 Flag 试一下。 -
restartreplace:文件被占用时提示重启后替换。 -
regserver/regtypelib:安装时注册 DLL/OCX/类型库,常见于老式组件。 -
recursesubdirs:配合 Source 通配符,递归打包所有子目录。 -
excludes:排除不需要的文件,比如Excludes: "*.pdb,*.obj"。
建议把版本控制文件和可能影响后续升级的文件分开处理。比如 config.ini 这种用户配置,安装时如果已存在,用
skipifsourcedoesntexist
和
onlyifdoesntexist
组合,避免覆盖用户配置。
注意:默认情况下,Inno Setup 在安装时如果遇到同名文件,会“询问是否覆盖”或者按版本号覆盖。如果你不想要这些烦人的弹窗,可以在 [Setup] 段设置
DisableDirPage、DisableProgramGroupPage等选项,并在 [Files] 段统一加Flags: ignoreversion,这样升级安装就会安静很多。
Icons 段的权限区分
Icons 段有一个容易忽略的知识点:
Tasks
参数。它允许你为某个快捷方式绑定到“可选安装任务”,用户在安装时勾选/取消某项任务,对应的快捷方式才会创建。举个例子:
[Tasks]
Name: "desktopicon"; Description: "创建桌面快捷方式"; GroupDescription: "附加任务:"
[Icons]
Name: "{group}\MyTool"; Filename: "{app}\mytool.exe"
Name: "{commondesktop}\MyTool"; Filename: "{app}\mytool.exe"; Tasks: desktopicon
这样桌面快捷方式就默认不建,只有用户勾选了“创建桌面快捷方式”才会创建。比较符合很多软件的安装习惯。
Registry 段的写入与回滚
写注册表时建议先想想能不能不写。Windows 允许软件通过相对路径保存配置(比如放在安装目录或
%APPDATA%
下),如果没必要,尽量少写注册表,因为注册表清理不干净很容易被安全软件报毒。但有些场景绕不开,比如文件关联。下面是一个把
.mytool
文件关联到你程序的写法:
[Registry]
Root: HKA; Subkey: "Software\Classes\.mytool\DefaultIcon"; ValueType: string; ValueData: "{app}\mytool.exe,0"
Root: HKA; Subkey: "Software\Classes\.mytool\shell\open\command"; ValueType: string; ValueData: """{app}\mytool.exe"" ""%1"""
这里的
HKA
是“HKEY_CURRENT_USER 优先,失败再写 HKEY_LOCAL_MACHINE”的缩写,对非管理员安装比较友好。卸载时 Inno Setup 会记住它写过的键值,主动删除,不需要你额外写清理逻辑,前提是你在 [Registry] 段写了它。
Run 段的执行技巧
Run 段最常见的场景是“安装完成打开程序”。如果要同时支持安装完运行,又不想在静默安装时也弹出来,可以这样:
[Run]
Filename: "{app}\mytool.exe"; Description: "立即运行 MyTool"; Flags: nowait postinstall skipifsilent
postinstall
表示安装结束后出现在“完成”页面里,
nowait
表示安装程序不等待程序退出,
skipifsilent
表示静默安装时不执行。这组合非常常用。
3.3 常量与预处理器
Inno Setup 里最强大的“魔法值”就是常量(Constants)。这些常量以
{xxx}
的形式出现在脚本里,编译器在运行时把它们替换成真实路径。常见的就那么几个:
-
{app}:当前应用安装目录。程序的主逻辑都往这里放。 -
{autopf}:Program Files 目录,在 64 位系统上会自动映射到 Program Files。 -
{pf}:Program Files(32 位视角)。 -
{commondesktop}:公共桌面目录。 -
{userdesktop}:当前用户桌面目录。 -
{commonprograms}:公共开始菜单程序目录。 -
{userprograms}:当前用户开始菜单程序目录。 -
{tmp}:安装时临时目录,适合放一些安装时用、装完就删的文件。 -
{sd}:安装包的源目录,也就是你双击安装包时,安装包所在目录。这个常用来放“额外依赖包”,比如安装前自动运行 vcredist_x86.exe。 -
{sys}:系统目录(System32),写驱动、写系统文件时用到。 -
{data}:在安装程序启动时创建的隐藏数据目录,配合[Dirs]段使用,很少见但有趣。
常量最大的作用是让脚本具有可移植性,不写死绝对路径。你的脚本只要写
{app}
,无论用户装到 D 盘还是 E 盘,安装程序都会自动把文件放到该放的位置。
预处理器(ISPP)则是另一层“编译时”能力。它能定义变量、条件分支、循环展开,甚至把文件列表批量生成。简单例子:
#define MyAppName "MyTool"
#define MyAppVersion "1.2.3"
[Setup]
AppName={#MyAppName}
AppVersion={#MyAppVersion}
这种
#define
宏定义的好处是,当你需要修改版本号时,只改一行,整个脚本里的相关引用都会同步更新。ISPP 还支持
#if
、
#for
等逻辑,在做多语言版本、定制化构建时尤其好用,可以把一套脚本配置出不同产品。不过新手阶段不用急着精通预处理器,能看懂
#define
就行,用多了自然熟。
4. 完整实操:一个真实项目的打包过程
上面讲的都是碎片化的知识点,接下来我带你完整走一遍一个真实场景的打包过程。假设你有一个简单的桌面工具 MyTool,它包含一个主程序 mytool.exe、一个配置文件 config.ini、一个依赖的 dll 文件 runtime.dll,还有一套资源文件夹 assets。同时你需要:安装后默认给所有用户创建开始菜单和桌面快捷方式;把一个 .mytool 文件类型关联到主程序;安装完成时提供“立即运行”选项;并确保卸载时删除所有相关文件。
4.1 项目背景与打包需求
这个项目需求整理成清单就是:
- 安装目录默认在 Program Files,安装时允许用户修改路径。
- 要打包的文件分为两层:exe/dll/资源文件夹。
- 需要创建开始菜单程序和桌面快捷方式。
- 要写注册表实现 .mytool 文件关联。
- 安装完成后要默认勾选“运行 MyTool”。
- 卸载时要清理干净,包括关联的注册表和生成的快捷方式。
基于这些需求,我通常会先把发布目录 D:\release 整理成最终要交付的样子:
D:\release\mytool.exe
D:\release\runtime.dll
D:\release\config.ini
D:\release\assets\icon.png
D:\release\assets\data.json
这样打包时 Source 指向 D:\release* 即可,不会把开发环境里的源码、调试中间文件带进去。
4.2 编写完整脚本
在 Inno Setup 里新建一个脚本(File -> New),会自动生成一段默认模板,然后我们逐段修改成下面这样:
[Setup]
AppName=MyTool
AppVersion=1.0.0
AppPublisher=Example Studio
AppPublisherURL=https://www.example.com
DefaultDirName={autopf}\MyTool
DefaultGroupName=MyTool
DisableProgramGroupPage=yes
OutputDir=D:\output
OutputBaseFilename=MyToolSetup_1.0.0
Compression=lzma2
SolidCompression=yes
WizardStyle=modern
PrivilegesRequired=admin
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
[Languages]
Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "创建桌面快捷方式"; GroupDescription: "附加任务:"; Flags: unchecked
[Files]
Source: "D:\release\mytool.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "D:\release\runtime.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "D:\release\config.ini"; DestDir: "{app}"; Flags: ignoreversion onlyifdoesntexist
Source: "D:\release\assets\*"; DestDir: "{app}\assets"; Flags: ignoreversion recursesubdirs
[Icons]
Name: "{group}\MyTool"; Filename: "{app}\mytool.exe"
Name: "{commondesktop}\MyTool"; Filename: "{app}\mytool.exe"; Tasks: desktopicon
[Registry]
Root: HKA; Subkey: "Software\Classes\.mytool\DefaultIcon"; ValueType: string; ValueData: "{app}\mytool.exe,0"
Root: HKA; Subkey: "Software\Classes\.mytool\shell\open\command"; ValueType: string; ValueData: """{app}\mytool.exe"" ""%1"""
[Run]
Filename: "{app}\mytool.exe"; Description: "立即运行 MyTool"; Flags: nowait postinstall skipifsilent
这段脚本覆盖了我们刚才提到的所有需求。这里有几点值得展开说:
PrivilegesRequired 与权限
。我在这里设置
PrivilegesRequired=admin
,意思是安装时要求管理员权限。因为默认装到 Program Files 需要写权限,且文件关联写入 HKCU/HKLM 也可能需要权限。如果你只是给当前用户装个小工具,可以设成
lowest
或者
none
,那样安装时不会弹 UAC 提示,体验更轻。但注意,装到
{userappdata}
之类用户目录才适合免管理员权限。
ArchitecturesAllowed=x64compatible
和
ArchitecturesInstallIn64BitMode=x64compatible
是 Inno Setup 近几个版本支持的新写法,它的意思是“安装包兼容 64 位和 32 位系统,但以 64 位模式进行安装”。如果你确认软件只面向 64 位系统,可以这样写;如果还需要兼容 32 位,就删除这两行。这个设计就是为了解决旧写法里
x64
与
x86
架构判断的混乱问题。
config.ini 的 onlyifdoesntexist
。这个 flag 是刻意加的。假设用户是升级安装,之前在安装目录里保存过一些自定义配置,我们不希望重装时把它覆盖成默认值。
onlyifdoesntexist
会检查目标文件是否已存在,如果存在则跳过。对于数据库文件、配置文件这类用户数据,这是非常实用的保护策略。
Registry 用 HKA
。前面提过,HKA 会优先写入当前用户,这样在非管理员安装时也能成功写入文件关联。卸载时 Inno Setup 会清理通过
Root: HKA
写入的键,这比直接在 HKCU 或 HKLM 写要安全得多。
4.3 编译与验证
脚本写好后,点击 Compile(Ctrl+F9)编译。如果脚本有语法错误,编译器会弹出错误信息和所在行,修改后重新编译即可。编译成功后,在
D:\output
目录下会生成
MyToolSetup_1.0.0.exe
。
测试时不要只在本机装,最好开一台干净的虚拟机或者换一台没装过这个软件的机器。原因很简单:本机可能有残留文件、DLL、注册表项,会让你误以为安装包是好的,实际上换个环境就露馅了。
验证安装包时可以重点看几个方面:
- 安装完成后,安装目录里的文件是否完整,路径是否正确。
- 开始菜单和桌面快捷方式是否按要求创建。
- 右键一个 .mytool 文件,能否直接用 MyTool 打开。
- 控制面板的“卸载程序”里有没有正确的名称/版本/图标。
- 卸载后,安装目录、快捷方式、注册表遗留项是否被清理干净。
4.4 静默安装与自动化场景
很多企业部署场景需要静默安装,也就是不弹向导界面,直接后台装完。Inno Setup 支持命令行参数,常用的有:
MyToolSetup_1.0.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART
/VERYSILENT
表示全程不显示界面和进度条,
/SUPPRESSMSGBOXES
会抑制所有弹窗,
/NORESTART
禁止重启。如果你希望静默安装时也保存安装日志,可以加
/LOG="C:\install.log"
。日志文件在排查安装失败时非常有用,它会记录每个文件复制、注册表写入、命令执行的结果。
静默安装的默认安装目录是
DefaultDirName
,如果你要用脚本指定不同目录,可以用
/DIR="D:\CustomDir"
。但是要注意,路径不能带引号且不能以
\
结尾,否则可能解析错误。另外,如果用户已经安装了旧版本,新版默认会覆盖安装,除非你在脚本里做了版本判断。
4.5 数字签名与发布
生成安装包以后,还有一件重要的事:数字签名。没有签名的 exe 在 Windows 10/11 上首次运行时,SmartScreen 会提示“Windows 已保护你的电脑”,这对很多非技术用户来说基本等于劝退。签名流程通常是用代码签名证书(OV 或 EV 证书)配合 signtool 工具执行:
signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 /sha1 证书指纹 MyToolSetup_1.0.0.exe
如果暂时没有证书,至少也要在项目设置里为 exe 添加文件的版本信息、公司名,减少被杀毒软件误报的概率。在 [Setup] 段可以使用
VersionInfoCompany
、
VersionInfoDescription
、
VersionInfoProductName
等字段补充这些元数据。证书一般要花钱买,小型个人项目可以考虑免费的证书方案,或者先用自签名证书测试,但发布给大众用户前建议还是买正式证书。
5. 进阶技巧与常见问题排查实录
工具用得越久,踩的坑就越多,这里挑几个我印象最深的点来说,它们也是新手最容易卡住的地方。
5.1 常见问题速查表
| 问题现象 | 原因与解决 |
|---|---|
| 安装时提示“文件正在被占用”,无法覆盖 |
检查是否有旧版本程序正在运行。在 [Files] 对应项加
restartreplace
,或使用
CloseApplications=yes
让安装前自动关闭目标 exe
|
| 安装完成后,双击 exe 无反应 | 可能是缺少运行库或 DLL 未拷贝完整。检查 Files 段的路径和通配符是否正确。建议先手动解压安装包,查看安装出的目录是否和 release 目录一致 |
| 卸载后残留安装目录或配置 | 在 [UninstallDelete] 段里加 Type: filesandordirs; Name: "{app}",强制删除整个安装目录。注册表清理则用 [UninstallDelete] 的 Registry 写法 |
| 桌面快捷方式总是“无法找到目标” |
检查 Icons 段的 Filename 是不是写成了相对路径。要写
{app}\mytool.exe
,不要只写
mytool.exe
|
| 安装包被杀毒软件误报 | 用 UPX 压缩或加壳的程序容易触发误报,尽量发布不加壳的原版 exe。同时完善版本信息、公司信息,申请数字签名是降低误报最直接的办法 |
| 静默安装时用户没权限安装 |
在 [Setup] 段设置
PrivilegesRequired=admin
,这样静默安装也会触发 UAC 提权。同时脚本里 DonotUse “{autopf}” 作为默认目录时,要确保用户目录有写入权限
|
| 升级安装时配置文件被覆盖 |
给 config.ini 加
onlyifdoesntexist
,或者用 [Code] 在安装前把已有文件备份出来
|
5.2 安装体验优化的几个细节
Inno Setup 默认的向导界面是比较老式的,但你可以通过
WizardStyle=modern
(新版默认已经启用)让它看起来更接近现代 Windows 安装程序。如果你还想进一步美化,可以设置
WizardImageFile
和
WizardSmallImageFile
自定义左侧横幅图和顶部小图标,图片格式支持 bmp 或 jpg。很多商业软件那种“品牌感满满的安装包”,其实都是用 Inno Setup 换了两张图做出来的。
另外,安装包的文件体积优化也值得花心思。Inno Setup 的 lzma2 压缩率在同类工具里算非常高的,但如果你的软件里有很多图片、PDF 这类已经压缩过的资源,再压也压不了多少。相反,如果有一堆文本、JSON、本地数据库,压缩收益就很明显。所以不用一味追求“压缩率最高”,必要时可以在 [Setup] 段针对不同文件设置不同的
Compression
级别。
多语言这块,我之前项目里同时加了中文、英文界面,用户安装时可以根据系统语言自动选择。设置方法很简单,在 [Languages] 段里加多个语言条目,中文的 MessagesFile 指向
compiler:Languages\ChineseSimplified.isl
就行。注意,默认英文语言必须保留,否则某些控件可能出现问题。
5.3 用 [Code] 段处理“安装时必须判断的复杂逻辑”
很多安装包的需求不是光靠标准段位能解决的,比如“安装时要检测系统是否安装了某个依赖,没有就静默安装”“安装时要读取配置文件生成不同的目录结构”“安装完成后要修改某个 ini 文件”。这时就需要在 [Code] 段里写 Pascal 脚本。
简单举例:检测系统是否安装了 .NET 运行时,如果没装就提示并打开下载页。这里用到
InitializeSetup()
函数:
[Code]
function InitializeSetup(): Boolean;
begin
if not RegKeyExists(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full') then
begin
MsgBox('检测到未安装 .NET Framework 4.x,请先安装后再运行本程序。', mbInformation, MB_OK);
Result := False;
end
else
Result := True;
end;
这种“自定义检测 + 阻断安装”的逻辑在实际项目中非常常见。Inno Setup 的 [Code] 段提供了大量回调函数(InitializeSetup、CurStepChanged、NextButtonClick 等),它们定义了安装过程中各个阶段介入的时机,你可以在里面做几乎任何事情。
对新手来说,[Code] 段可能有点门槛,但它的语法是 Pascal 风格,和 Delphi 系列很像,有编程基础的人上手很快。如果完全没有编程基础,遇到这类需求,可以先在网上找现成的代码片段,改改参数就能用。大家基本都是这么过来的。
5.4 备份、自动化与持续集成的串联
最后说一个容易被忽略的点:安装包构建一定要和你的发布流程绑定。以前我手工在 Inno Setup 里点编译,每次都担心漏掉文件。后来我把编译命令集成到了 CI(比如 Jenkins、GitLab CI)里,用命令行编译脚本:
ISCC.exe MyTool.iss
ISCC.exe
是 Inno Setup 编译器在命令行下的入口,位于安装目录下。你可以在 CI 里先构建好 release 文件,再调用 ISCC 生成安装包,再自动签名、上传。这样整个发布过程就自动化了,不会出现“本地能装,流水线装不上”的尴尬。命令行还支持覆盖
OutputBaseFilename
、
VersionInfoVersion
等参数,比如:
ISCC.exe /DMyAppVersion=2.0 MyTool.iss
通过
/D
把版本号作为宏传入脚本,脚本里用
{#MyAppVersion}
引用,构建不同的版本就不用手动改脚本了。再配合输出目录规则,就能做到“一键发布多版本、多架构安装包”。
6. 写在最后的几点体会
说了这么多,其实 Inno Setup 的核心理念就一句话:一切皆脚本,脚本即配置。它不像某些商业工具那样把逻辑藏在界面后面,而是把整个安装过程变成了一篇可以阅读、修改、交付的文本。好处是显而易见的——当你有新需求,或者需要排查问题,打开 .iss 脚本,所有环节一目了然。
我个人在使用中最大的感受是:早期觉得写脚本麻烦,总想着找“拖拽式”工具,但用了段时间 Inno Setup 后,反而喜欢上了这种“用文本定义安装行为”的方式。因为它可控、可审阅、可复用,还方便纳入版本管理。你根本不用担心打包工具版本升级后旧项目没法打开——一个 .iss 文件放个十年八年,依然能被新版本编译。
如果你正准备给 Windows 软件做安装包,我的建议是别再花时间纠结工具选型了,直接上手 Inno Setup。先跟着教程跑通第一个包,然后从实际需求出发一个个加功能。每当你遇到一个“这个安装包能不能这样做”的想法,就去查官方文档或者搜索代码片段,一次解决一个问题。用不了几个项目,你就会发现自己已经成了身边人眼里的“打包大师”。最后再分享一个小技巧:把平时用到的脚本片段单独存起来,比如“中文多语言”“文件关联”“静默安装调用”“检测依赖”,下次做新项目直接复制修改,效率会翻倍。
更多推荐



所有评论(0)