
简介面向Inno Setup开发者的自定义安装界面资源包主要解决默认安装向导外观单一、难以整合产品品牌的问题涵盖欢迎页、许可协议、目录选择、进度与完成页等界面模块适合需要为Windows客户端快速制作专业安装程序的开发者。压缩包共136个文件以64个isl脚本、23个png界面图、19个psd设计源文件、11个dll运行库及exe辅助工具为主整体约105.4MB目录结构清晰。资源内置Inno Setup增强版封装已包含对.NET Framework 4的封装支持可直接复用Code.iss为界面代码version.h配置文件中可方便修改应用名称、公司、版本号等品牌信息。同时提供PSD源文件与PNG图片temp目录下的界面图可自由替换App目录下的程序文件按需覆盖后修改脚本即可完成整套安装界面定制。已有1744人学习下载适合中高级Windows安装包开发者参考并二次开发。1. inno setup自定义安装界面先想清楚你要动的是配置还是脚本交付 Windows 桌面软件的时候安装包界面往往是最容易被低估的细节。inno setup自定义安装界面 这个需求说穿了就是一句话默认的 Inno Setup 向导能装完软件但界面长得很“通用”换成自家品牌和交互逻辑之后客户的第一印象会立刻不一样。这个方向能解决三件事品牌统一、选项引导、把“是否创建快捷方式”“选择安装模式”这类判断放进可视化的页面里。适合谁有桌面产品要交付的开发者、要给客户做定制安装包的实施工程师、以及被采购方要求“安装包看起来正规些”的小团队。别急着找现成皮肤先搞清楚 Inno Setup 提供的两层修改入口后面就能按需改到位。2. 零代码入口与脚本入口两条修改路径怎么选2.1 [Setup]与[Messages]段换品牌名、按钮文字与欢迎页的最短路径Inno Setup 的安装包简介文件.iss本身就是一大块配置。先看一段最常见的定制配置这段工作不需要写一行 Pascal 脚本只需要在打包前改配置项[Setup] ; 这些是安装包整体层面的定制项 AppNameHarborClient AppVersion2.1.0 AppPublisher示例科技 DefaultDirName{autopf}\HarborClient DisableWelcomePageno ; modern 风格更扁平classic 是传统分组样式 WizardStylemodern SetupIconFileassets\setup.ico WizardImageFileassets\banner.bmp WizardSmallImageFileassets\small.bmp [Messages] WelcomeLabel1欢迎安装 HarborClient WelcomeLabel2这个向导会帮你在本机部署 HarborClient 客户端。%n%n如果安装过旧版本请先卸载再继续。 ButtonNext下一步(N) ButtonBack上一步(B) ButtonInstall开始安装(I) ButtonFinish完成(F)这段配置主要解决“想换品牌又不想碰代码”的场景。[Setup]段里AppName与AppPublisher会显示在安装向导的标题栏和欢迎页上WizardStyle决定整体风格modern 偏扁平、classic 偏传统SetupIconFile换的是安装包 exe 的文件图标WizardImageFile与WizardSmallImageFile分别对应向导左侧的大图和左上角的小图这两个文件走的是 BMP/JPG 位图路线后面避坑章会专门讲透明图片在这里翻车的问题。[Messages]段则负责把按钮文字全部换成自己的语言习惯比如ButtonInstall是从“安装”页面点下去的按钮ButtonFinish是完成后右下角的“完成”。注意行尾的(N)是键盘快捷键写法按 AltN 就能触发下一步这个细节在客户现场演示时很加分。你能在这里做的定制本质上是给 Inno Setup 的默认控件换文字和图片不改控件结构。2.2 InitializeWizard事件与WizardForm接管向导窗体的第一行脚本当需求超过“换名字换图”之后就要进入脚本入口了。Inno Setup 的脚本语言是对象 Pascal 的一个子集入口点就是事件函数。在向导窗体创建完成之后、显示给用户之前InitializeWizard会被调用。这是修改窗体属性的最佳时机因为此时所有页面控件都已经创建完毕你改什么它都能立刻生效。[Code] procedure InitializeWizard; begin // WizardForm 是整个安装向导的主窗体所有子页面都在它上面 WizardForm.Color : clWindow; WizardForm.Caption : HarborClient 安装向导; // 欢迎页顶部大标题调整字号和颜色 WizardForm.WelcomeLabel1.Font.Size : 11; WizardForm.WelcomeLabel1.Font.Color : clNavy; // 下一步/上一步按钮宽度拉宽避免文字被截断 WizardForm.NextButton.Width : ScaleX(120); WizardForm.BackButton.Width : ScaleX(120); end;这里最核心的东西是WizardForm这个全局变量。它代表整个安装向导窗体下面挂着WelcomeLabel1、NextButton、BackButton、BitmapImage等一批现成控件。你在 [Setup] 段看到的所有文案本质上都是给这些控件的默认值脚本修改则可以做到更细字体颜色、控件宽度、按钮间距、甚至是某个页面在向导中的显示顺序。ScaleX和ScaleY是坐标换算函数。Inno Setup 内部以 96 DPI 为基准设计界面当目标机器开了 125% 或 150% 缩放时直接写固定像素会错位套一层ScaleX才能保证在不同分辨率下表现一致。这条是新手最容易忽略的细节也是后面避坑章要展开讲的主题。2.3 选型判断什么时候只在Messages改什么时候必须上[Code]把两条路摆在一起判断标准其实很清晰。只换品牌信息、按钮文字、欢迎语、默认图标[Setup][Messages]就够半小时能交付。要插入新的输入页面、勾选框、单选按钮或者在点击下一步时做环境检测就必须上[Code]用InitializeWizard创建页面和控件用事件函数处理逻辑。还有一种情况要提前给读者打预防针如果你期待的“自定义安装界面”是那种彻底重绘窗体、左侧导航栏、全自定义动画的现代安装器外观Inno Setup 默认做不到。它能改的是窗体属性、控件状态与页面流程但窗体骨架是固定的。做完全换肤需要借助 VCL 样式EnableVclStyles或干脆评估其他专用安装工具这个边界提前知道能省下不少折腾时间。对这个项目来说绝大多数“看起来更正规”的需求脚本入口已经能覆盖。3. 用TInputOptionWizardPage做一个带选项的自定义安装界面完整脚本与参数说明3.1 页面挂载点与控件布局把自建页面插到安装步骤的哪里先拆一个最常见的真实需求安装时让用户选择“标准模式”还是“兼容模式”同时决定要不要在桌面创建快捷方式。这需要 Inno Setup 的预设组件TInputOptionWizardPage来做一个单选页面再用TNewCheckBox在页面下方追加一个复选框。页面插在哪个位置由CreateInputOptionPage的第一个参数决定。Inno Setup 内置页面有固定的 ID比如wpWelcome欢迎页、wpSelectTasks选择任务页、wpReady准备安装页。把自建页面挂在wpSelectTasks之后意味着用户先选任务、再选安装模式、最后看到准备安装页这个顺序符合大多数商业软件的引导习惯。布局上注意一个关键概念TInputOptionWizardPage内部有一个Surface属性它是页面上用来承载控件的容器。所有往自定义页面里追加的控件Parent必须指向ModePage.Surface而不是直接指向ModePage或WizardForm否则控件会跑到窗口外或者干脆不显示。3.2 完整可编译脚本创建页面、读取勾选、应用结果下面这段脚本是完整可编译的建议直接抄到项目里再按需调整注释里的业务逻辑[Setup] AppNameHarborClient AppVersion2.1.0 DefaultDirName{autopf}\HarborClient WizardStylemodern [Code] var ModePage: TInputOptionWizardPage; DesktopIconBox: TNewCheckBox; InstallMode: Integer; procedure InitializeWizard; begin // 1. 创建安装模式选择页插在“选择任务”页之后 ModePage : CreateInputOptionPage( wpSelectTasks, 选择安装模式, 根据目标机器情况决定安装行为, 标准模式适合绝大多数机器兼容模式会关闭高开销特性。, True); ModePage.Add(标准模式推荐); ModePage.Add(兼容模式降低占用); ModePage.Values[0] : True; // 2. 在模式选择页下方追加一个复选框 DesktopIconBox : TNewCheckBox.Create(ModePage); DesktopIconBox.Parent : ModePage.Surface; DesktopIconBox.Left : ScaleX(8); DesktopIconBox.Top : ModePage.Values[0].Top ScaleY(30); DesktopIconBox.Width : ScaleX(260); DesktopIconBox.Height : ScaleY(21); DesktopIconBox.Caption : 同时在桌面创建快捷方式; DesktopIconBox.Checked : True; end; function NextButtonClick(CurPageID: Integer): Boolean; var FreeSpace: Int64; begin Result : True; if CurPageID ModePage.ID then begin InstallMode : ModePage.SelectedValueIndex; // 标准模式下做一次磁盘空间检测失败则阻止用户继续 if InstallMode 0 then begin if GetSpaceOnDisk(ExpandConstant({sd}), FreeSpace) and (FreeSpace 500 * 1024 * 1024) then begin MsgBox(磁盘剩余空间不足 500MB请先清理。, mbError, MB_OK); Result : False; end; end; end; end; procedure CurStepChanged(CurStep: TSetupStep); begin // 文件复制完成之后再创建桌面快捷方式 if CurStep ssPostInstall then begin if DesktopIconBox.Checked then CreateShellShortcut( desktop, ExpandConstant({autopf}\HarborClient\harbor.exe), , ExpandConstant({autopf}\HarborClient), HarborClient 客户端, ExpandConstant({autopf}\HarborClient\harbor.exe), 0); end; end;逐段说明一下脚本干了什么。CreateInputOptionPage的五个参数分别是插入位置、页面标题、页面主描述、页面副描述、是否可选。最后一个参数传True时页面上会有一个“取消勾选此页”之类的退出入口实际含义是此页面是否允许用户通过取消勾选跳过传True后用户仍可以正常进入下一步传False则强制必须停留这里有版本差异常见做法是先传True再在NextButtonClick里按业务校验拦截可控性更强。ModePage.Add每调用一次就增加一个单选按钮返回值会被放入Values数组运行时通过SelectedValueIndex拿到用户选中的索引。DesktopIconBox挂到Surface上之后用Left、Top、Width、Height手动定位坐标全部经过ScaleX/ScaleY处理这是保证高分屏不翻车的前提。NextButtonClick是点击“下一步”时触发的事件函数返回False会阻止页面前进适合做环境检查CurStepChanged监听安装步骤变化ssPostInstall在文件复制完成后触发此时创建快捷方式目标文件一定已经落盘。3.3 NextButtonClick与CurStepChanged逻辑必须在正确的事件里执行事件函数触发时机典型用途InitializeWizard向导窗体创建后、显示前创建自定义页面、改控件属性、加载图片ShouldSkipPage每页显示前按条件跳过某一步比如兼容模式下跳过附加功能页NextButtonClick点击下一步时还没真正切换页面校验用户输入、环境检测返回 False 中止流程CurStepChanged安装步骤状态变化时文件复制后创建快捷方式、写注册表、启动服务InstallMode 读取点点击下一步后把用户选择存入全局变量供后续步骤消费这里最常见的误用是把校验逻辑写进InitializeWizard。那个阶段用户还没做任何选择页面数据是默认值校验没有意义。正确做法是把“读取用户选择”放在NextButtonClick里把“应用选择结果”放在CurStepChanged或安装后的Run条目里两个事件各管一段出问题也容易定位。另一个容易踩的点是CreateShellShortcut的版本依赖。这个内置函数是较新版本 Inno Setup 才有的如果你的环境还在用旧版编译器编译会直接报Undefined identifier。备选方案是用[Tasks]段内置的桌面图标任务在[Tasks]里定义desktopicon用WizardForm.TasksList.Checked[索引]同步状态这样旧版本也能跑。不过既然已经在新环境上推进建议直接用内置函数代码更短。4. 自定义安装界面避坑布局失效、图片变色与脚本报错怎么排查4.1 背景色改完页面上的文字像隐身了一样现象在InitializeWizard里把WizardForm.Color改成深色比如clBlack之后欢迎页标题、正文文字全部看不见了。原因Inno Setup 默认控件文字颜色是接近黑色的clWindowText深色背景下黑字压黑底不是控件消失是文字和背景融在一起了。解决改背景的同时要把所有会出现在这个背景上的文字控件颜色一起改掉典型的是WizardForm.WelcomeLabel1、WizardForm.WelcomeLabel2、WizardForm.PageNameLabel和WizardForm.PageDescriptionLabel。参考写法WizardForm.WelcomeLabel1.Font.Color : clWhite; WizardForm.WelcomeLabel2.Font.Color : clWhite;如果是自建页面上的TNewStaticText或TNewCheckBox同样要设置Font.Color。记住一个原则背景色变更不是单点操作它牵动页面上所有控件的前景色改之前先列出页面上会出现的全部控件清单。4.2 高分屏下控件叠在一起DPI缩放不是玄学现象在开发机100% 缩放上排版正常到客户现场的一台 150% 缩放的笔记本上自定义页面的复选框和单选按钮叠成一片。原因Inno Setup 支持 DPI 感知但前提是你在脚本里正确使用了ScaleX/ScaleY。直接写死Left : 8的控件在高分屏下坐标不跟随缩放视觉上必然错位。解决所有手工坐标都走ScaleX/ScaleY转换同时用现成控件的Top做相对定位。比如第 3 章里DesktopIconBox.Top : ModePage.Values[0].Top ScaleY(30)就是拿单选按钮的实际位置做基准再往下偏移 30 像素而不是写死Top : 108。另外Font.Size不需要缩放Pascal 脚本里字号本来就按点阵计算系统会自己处理。4.3 PNG透明区域在安装包里变成黑色块现象给[Setup]段的WizardImageFile配了一张漂亮的透明 PNG编译时直接报错或者编译过了但安装界面里透明区域变成黑块。原因WizardImageFile和WizardSmallImageFile这两个配置项从老版本开始就只认 BMP 与 JPG不认 PNG。PNG 的 Alpha 通道在这里没有对应实现强行使用会在编译阶段被拒绝。解决走 [Setup] 段就用 BMP 或者 JPG透明需求用 BMP 指定透明色处理实在要用透明 PNG改在InitializeWizard里用TBitmapImage加载并由代码设置BackColor与显示位置。多数团队最终图省事直接把左侧大图换成不透明 JPG这是最稳妥的。4.4 编译报Undefined identifier先查声明顺序再查ISPP现象脚本写好后按编译报Undefined identifier: ModePage或者Unknown.原因分两类。一类是变量声明顺序问题Pascal 脚本要求先声明后使用var声明必须放在所有procedure之前如果InitializeWizard里用的变量声明写在函数后面编译器就会报未定义。另一类是版本问题CreateShellShortcut这类新函数在老版本 Inno Setup 里不存在编译通不过。解决先把所有var声明集中放到[Code]顶部再确认编译用的 iscc 是较新版本如果你用了 ISPP 预处理脚本里出现#include、{#emit}这类东西检查预处理代码的变量作用域ISPP 的变量和 Pascal 脚本变量是两套体系不能混用。4.5 卸载程序把你的自定义界面丢了现象安装界面改得很有品牌感客户卸载时弹出来的却是默认蓝条向导像安装包做了一半。原因安装程序和卸载程序是两份独立的程序安装时的InitializeWizard只作用于安装向导。卸载程序也有自己的WizardForm实例它的事件函数是InitializeUninstallWizard默认不修改的话自然回到原始状态。解决在同一个 .iss 里补一个卸载事件入口procedure InitializeUninstallWizard; begin UninstallWizardForm.Color : clWindow; UninstallWizardForm.Caption : HarborClient 卸载向导; end;UninstallWizardForm是卸载向导的全局窗体变量Inno Setup 对它的操作方式和安装向导基本一致。如果你的自定义逻辑比较多把这个入口单独抽成一个文件安装和卸载两边各自调用保证一致体验。5. 把自定义界面沉淀成一套可复用的品牌模板做到这里你已经能按需求改文字、加页面、调布局、补事件了。接下来值得做的一件事把第 2 章和第 3 章的代码抽成一个公共的branding.inc文件在项目里用#include引入。这样每个新项目打包时只需要写业务逻辑界面风格统一由一份文件维护。常见的目录结构是这样branding/ branding.inc // 所有界面定制脚本 assets/ setup.ico banner.bmp small.bmp project/ harbor.iss // 业务脚本顶部 #include ..\branding\branding.inc在 CI 环境里命令行编译的参数也可以把品牌变量传进去比如用 iscc.exe 编译时指定/DBrandNameHarborClient脚本里用{#emit}读取预处理变量同一套模板就能产出不同客户版本的安装包。打包完成后我一般会做三件验证在干净的虚拟机里跑一遍完整安装流程检查每个页面在 100% 和 150% 缩放下的截图跑一遍卸载流程确认卸载事件里的自定义设置生效再看一眼任务管理器确认安装过程中没有残留进程。这套验证动作是我之前吃过亏换来的教训——UI 改动不影响安装逻辑但安装逻辑出问题往往要从 UI 操作开始排查界面和流程在安装器里本来就是一体。希望帮到你。本文还有配套的精品资源点击获取