资讯动态

Inno Setup实战:打造智能安装包,解决依赖与开机启动难题

发布时间:2026/8/8 3:55:08 来源:尧图企业网站定制
1. 从“能运行”到“开箱即用”为什么你的程序需要一个真正的安装包你花了好几个月终于把那个用 Python 写的自动化工具或者用 C 开发的小工具又或者是基于 Electron 的桌面应用给搞定了。功能测试一切正常你兴冲冲地把一个压缩包扔给同事或者客户。结果呢对方反馈接踵而至“哥们你这程序打不开啊提示缺少什么 DLL”、“我电脑上没装 Python运行不了”、“怎么设置开机启动啊每次都要手动点开好麻烦”。我相信很多独立开发者或者小团队的技术负责人都遇到过这种窘境。你的程序在开发环境里跑得飞起但到了用户手里就成了“薛定谔的软件”——能不能运行全看对方电脑的“缘分”。问题的核心在于我们交付的往往只是一个“程序本体”而非一个完整的“产品”。一个真正的产品应该为用户屏蔽掉所有技术细节和依赖复杂性做到下载、安装、使用三步走甚至安装后就能自动在后台提供服务开机启动。这就是 Inno Setup 这类安装包制作工具的价值所在。它不仅仅是一个“打包工具”更是一个“用户体验设计工具”和“部署保障工具”。通过它我们可以将程序本体、运行时环境如 .NET Framework, VC Redistributable, Java JRE、配置文件、注册表项、甚至后续的更新逻辑打包成一个专业的、向导式的安装程序.exe。用户双击后只需要点击“下一步”、“我同意”、“安装”即可获得一个立即可用的软件无需关心背后到底集成了哪些组件。最近在技术社区和搜索引擎上关于“依赖环境”和“开机启动”的讨论非常热络。比如“uniapp 运行报错 cli项目运行依赖本地的nodejs环境”这本质就是运行时环境缺失的问题而“笔记本开机后wifi启动慢”这类问题也从侧面反映了用户对系统启动后服务自动就绪的强需求。对于我们自己开发的工具如果是一个需要常驻的服务比如监控客户端、同步工具、自动化脚本开机自启就是刚需。手动让用户去创建快捷方式到启动文件夹既不专业也容易出错。因此今天我们就来深入聊聊如何用 Inno Setup 这个经典、免费且强大的工具打造一个不仅包含主程序还能自动安装依赖环境、并实现开机启动的专业级安装包。我会结合我多次交付内部工具和中小型商业软件的经验把其中的关键步骤、配置细节以及最容易踩的坑毫无保留地分享给你。2. Inno Setup 核心概念与项目结构解析在动手写脚本之前我们必须先理解 Inno Setup 是如何工作的以及一个标准的安装包项目包含哪些部分。这能帮助我们在后面编写脚本时清楚地知道每一行代码在干什么而不是机械地复制粘贴。Inno Setup 使用一种基于 Pascal 语道的脚本文件.iss来定义整个安装过程。这个脚本文件是纯文本的你可以用任何文本编辑器编辑但官方提供的 Inno Setup Compiler 界面一个简易的 IDE会更方便它有语法高亮和编译按钮。一个典型的安装过程可以分解为以下几个逻辑阶段而我们的脚本就是对这些阶段进行定义安装向导界面定义安装过程中出现的窗口、文字、选项框比如是否创建桌面快捷方式是否开机启动。这部分对应脚本中的[Setup]和[Tasks]等节。文件部署指定将哪些源文件你的程序文件、依赖的 DLL、配置文件等复制到用户电脑的哪个目录下。这是核心对应[Files]节。系统配置在用户电脑上创建注册表项、环境变量、开始菜单文件夹、关联文件类型等。对应[Registry],[Icons]等节。执行外部操作在安装前、中、后运行其他程序。这是我们用来安装依赖环境如 VC 运行库和设置开机启动的关键手段对应[Run]和[UninstallRun]节。卸载逻辑定义如何干净地移除你的软件包括删除哪些文件、清理哪些注册表项。一个专业的安装包必须包含完整的卸载功能对应[UninstallDelete]和卸载时的[Run]节。一个最基本的 .iss 脚本骨架如下; 脚本由 Inno Setup 脚本向导生成 ; 有关创建 Inno Setup 脚本文件的详细资料请查阅帮助文档 #define MyAppName “我的程序” #define MyAppVersion “1.0” #define MyAppPublisher “我的公司” #define MyAppExeName “MyApp.exe” [Setup] ; 注意: AppId 的值是单独标识该应用程序的唯一标识。 ; 不要为其他安装程序使用相同的 AppId 值。 ; (生成新的 GUID点击 工具|在 IDE 中生成 GUID。) AppId{{你的GUID} AppName{#MyAppName} AppVersion{#MyAppVersion} AppPublisher{#MyAppPublisher} DefaultDirName{autopf}\{#MyAppName} DefaultGroupName{#MyAppName} ; 移除下一行注释以在安装结束时禁止显示“Windows 保护了你的电脑”提示。 ;PrivilegesRequiredlowest OutputDir. OutputBaseFilenamemysetup Compressionlzma SolidCompressionyes WizardStylemodern [Languages] Name: “chinesesimplified”; MessagesFile: “compiler:Languages\ChineseSimplified.isl” [Tasks] Name: “desktopicon”; Description: “{cm:CreateDesktopIcon}”; GroupDescription: “{cm:AdditionalIcons}”; Flags: unchecked [Files] Source: “D:\MyProject\bin\Release\MyApp.exe”; DestDir: “{app}”; Flags: ignoreversion ; 注意: 不要在任何共享系统文件上使用“Flags: ignoreversion” [Icons] Name: “{group}\{#MyAppName}”; Filename: “{app}\{#MyAppName}” Name: “{commondesktop}\{#MyAppName}”; Filename: “{app}\{#MyAppName}”; Tasks: desktopicon [Run] Filename: “{app}\{#MyAppName}”; Description: “{cm:LaunchProgram,{#StringChange(MyAppName, ‘’, ‘’)}}”; Flags: nowait postinstall skipifsilent这个骨架脚本生成了一个非常基础的安装包。但我们的目标远不止于此。接下来我们将在这个骨架上重点强化两个能力智能安装依赖环境和配置开机启动。注意{app},{group},{pf}这些是 Inno Setup 的常量Constants它们会在安装时被动态替换为实际的路径例如{app}代表用户选择的安装目录。使用常量能让你的脚本更通用适应不同用户的系统设置。3. 实战为安装包集成运行时依赖环境这是让我们的程序实现“开箱即用”最关键的一步。依赖环境缺失是软件部署中最常见的问题没有之一。从热词中可以看到jdk安装包、.net framework 离线安装包、vc_redist等都是高频搜索词这正说明了用户和开发者对此的强烈需求。我们的策略是在安装主程序之前或之后静默地安装这些运行时库。通常我们将这些依赖包的安装放在主程序文件安装之后[Files]节并在安装最后一步[Run]节执行它们。为了用户体验通常采用静默安装参数如/quiet /norestart不让用户看到额外的安装界面。3.1 准备依赖安装包首先你需要获取依赖环境的离线安装包。以 Windows 平台最常见的几种为例Microsoft Visual C Redistributable (VC Redist)这是绝大多数 C/C 程序的基石。你需要根据你的程序编译时使用的 Visual Studio 版本准备对应的 x86 或 x64 安装包。例如VS 2015-2022 的合并版本VC_redist.x64.exe。可以从微软官网下载。.NET Framework / .NET Desktop Runtime如果你的程序基于 .NET Framework 4.x 或 .NET 5/6/7/8需要准备对应的运行时安装包。对于 .NET Core 及更高版本推荐使用“桌面运行时”Desktop Runtime因为它包含了运行桌面应用WinForms, WPF所需的一切。Java Runtime Environment (JRE)对于 Java 程序。你可以从 Adoptium 等网站下载.msi格式的离线安装包。其他如 DirectX End-User Runtimes、特定版本的 Node.js 等根据你的程序需要准备。关键点务必使用离线安装包通常文件较大几十MB到上百MB而不是在线安装器一个几MB的引导程序。因为你的用户安装时可能没有网络。3.2 修改脚本打包并静默安装依赖假设我们的主程序MyApp.exe依赖 VC 2015-2022 Redist x64 和 .NET 6.0 Desktop Runtime x64。我们将修改[Files]和[Run]节。首先在[Files]节中我们将这些依赖安装包也打包进我们的安装程序。通常我们会将它们放在一个子目录如deps\中以保持结构清晰。[Files] ; 主程序 Source: “D:\MyProject\bin\Release\MyApp.exe”; DestDir: “{app}”; Flags: ignoreversion ; 你可以继续添加其他资源文件如图片、配置文件等 ; Source: “D:\MyProject\config.ini”; DestDir: “{app}”; Flags: ignoreversion ; 依赖包 - 将它们复制到安装目录下的一个子文件夹避免污染根目录 Source: “D:\Dependencies\VC_redist.x64.exe”; DestDir: “{app}\deps”; Flags: ignoreversion deleteafterinstall Source: “D:\Dependencies\windowsdesktop-runtime-6.0.xx-win-x64.exe”; DestDir: “{app}\deps”; Flags: ignoreversion deleteafterinstall注意Flags中的deleteafterinstall。这个标志非常有用它告诉 Inno Setup 在安装过程结束后删除这个文件。这样依赖包只在安装时被临时解压到用户电脑上运行完后就被清理不会占用用户额外的磁盘空间。接下来在[Run]节中我们添加执行这些依赖安装的命令。这里有一个非常重要的技巧先检查系统是否已安装该依赖避免重复安装。重复安装虽然通常无害但会浪费用户时间并可能弹出不必要的重启提示。我们可以利用 Inno Setup 的Check参数和RegKeyExists,GetEnv等函数来实现条件执行。[Run] ; 静默安装 VC Redist (如果尚未安装) ; 通过检查注册表来判断是否已安装 Filename: “{app}\deps\VC_redist.x64.exe”; Parameters: “/install /quiet /norestart”; StatusMsg: “正在安装 Microsoft Visual C 运行库…”; Check: not VCRedistInstalled ; 静默安装 .NET 6 Desktop Runtime (如果尚未安装) ; 通过检查注册表和系统路径来判断 Filename: “{app}\deps\windowsdesktop-runtime-6.0.xx-win-x64.exe”; Parameters: “/install /quiet /norestart”; StatusMsg: “正在安装 .NET 6 桌面运行时…”; Check: not DotNetRuntimeInstalled ; 最后可选地运行主程序 Filename: “{app}\MyApp.exe”; Description: “运行 {#MyAppName}”; Flags: nowait postinstall skipifsilent3.3 实现自定义检查函数上面的Check: not VCRedistInstalled和Check: not DotNetRuntimeInstalled是自定义函数调用。我们需要在脚本的[Code]节这是一个用于编写 Pascal 代码的节中实现这些函数。[Code] // 函数检查 VC 2015-2022 Redist (x64) 是否已安装 function VCRedistInstalled: Boolean; var Version: String; begin // 通过注册表检查。不同版本的VC Redist有不同的GUID。 // 对于 VS 2015-2022 的合并包可以检查这个键 if RegQueryStringValue(HKLM, ‘SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64’, ‘Version’, Version) then begin // 如果找到了版本号说明已安装 Result : True; end else begin Result : False; end; end; // 函数检查 .NET 6 Desktop Runtime 是否已安装 function DotNetRuntimeInstalled: Boolean; var InstallRoot: String; begin // .NET Core/5 运行时信息通常在这个注册表路径下 if RegQueryStringValue(HKLM, ‘SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost\’, ‘Version’, InstallRoot) then begin // 这里我们简化处理只要找到了这个键就认为有某个版本的运行时。 // 更严谨的做法是读取版本号并与所需版本比较。 Result : True; end else begin Result : False; end; end;通过这样的设计我们的安装包就具备了“智能”安装依赖的能力。它会先探测用户的系统环境只安装缺失的组件从而让安装过程既完整又高效。4. 实现开机启动从用户选项到系统服务开机启动是很多工具类软件的必备功能。实现方式主要有三种各有优劣适用于不同场景启动文件夹快捷方式最简单将程序的快捷方式放入用户的启动文件夹。适合普通桌面应用需要用户登录后才启动。注册表自启动项将程序路径写入HKCU\Software\Microsoft\Windows\CurrentVersion\Run当前用户或HKLM\...\Run所有用户。比启动文件夹更隐蔽同样是用户登录后启动。Windows 服务最高级程序以系统服务形式运行无需用户登录即可启动拥有更高的权限和稳定性。适合后台守护进程。对于大多数桌面工具我们通常提供选项让用户选择是否开机启动采用第1或第2种方式。这里我们以“通过注册表项 用户可选任务”为例因为它更灵活且能通过安装脚本和卸载脚本统一管理。4.1 在安装向导中添加用户选项首先我们在[Tasks]节中添加一个任务Task让用户在安装时可以选择。[Tasks] Name: “desktopicon”; Description: “创建桌面快捷方式”; GroupDescription: “附加图标:”; Flags: unchecked Name: “autostart”; Description: “开机时自动启动 {#MyAppName}”; GroupDescription: “其他任务:”; Flags: unchecked这样安装界面上就会多出一个复选框“开机时自动启动 我的程序”。4.2 根据用户选择写入注册表然后我们在[Registry]节中根据用户是否勾选了autostart任务来决定是否创建注册表项。[Registry] ; 如果用户勾选了“开机启动”任务则在当前用户的Run键下创建自启动项 Root: HKCU; Subkey: “SOFTWARE\Microsoft\Windows\CurrentVersion\Run”; ValueType: string; ValueName: “{#MyAppName}”; ValueData: “{app}\MyApp.exe”; Flags: uninsdeletevalue; Tasks: autostart解释一下关键参数Root: HKCU写入当前用户HKEY_CURRENT_USER的注册表这样不需要管理员权限。如果希望为所有用户设置需要管理员权限并改用HKLM。Subkey自启动项的标准路径。ValueName项的名称这里我们直接用程序名。ValueData项的值即要运行的程序完整路径。{app}会被替换为实际的安装目录。Flags: uninsdeletevalue非常重要这个标志表示在卸载时会自动删除这个注册表值。这确保了我们的软件能够被干净地移除不会留下垃圾启动项。Tasks: autostart这个条件语句确保了只有用户勾选了autostart任务时这段注册表操作才会执行。4.3 进阶以管理员权限运行并注册系统服务如果你的程序是一个需要高权限、或者需要在用户登录前就运行的后台服务那么创建 Windows 服务是更专业的选择。这通常需要你的程序本身支持以服务模式运行例如在 .NET 中可以使用Topshelf或BackgroundService在 C 中可以调用服务控制管理器 API。在 Inno Setup 中我们可以通过[Run]节在安装后以管理员权限执行一个命令来注册服务。假设你的程序MyService.exe支持通过install参数安装服务。[Run] ; … 其他运行命令如安装依赖 … ; 注册为 Windows 服务需要管理员权限 Filename: “{app}\MyService.exe”; Parameters: “install”; StatusMsg: “正在注册系统服务…”; Flags: runhidden waituntilterminated; Check: IsAdminInstallMode ; 启动服务 Filename: “net”; Parameters: “start MyServiceName”; StatusMsg: “正在启动服务…”; Flags: runhidden waituntilterminated; Check: IsAdminInstallMode同时在[UninstallRun]节中我们需要在卸载前停止并删除服务。[UninstallRun] ; 卸载前停止并删除服务 Filename: “net”; Parameters: “stop MyServiceName”; Flags: runhidden waituntilterminated; Check: IsAdminInstallMode Filename: “{app}\MyService.exe”; Parameters: “uninstall”; Flags: runhidden waituntilterminated; Check: IsAdminInstallMode重要提示注册和操作 Windows 服务需要管理员权限。在[Setup]节中你需要设置PrivilegesRequiredadmin或PrivilegesRequiredOverridesAlloweddialog这样安装程序启动时就会请求管理员权限。IsAdminInstallMode函数在安装程序以管理员权限运行时返回True。5. 避坑指南与高级技巧打造更稳健的安装体验掌握了核心功能后我们还需要关注一些细节和边界情况这些往往是决定你的安装包是否专业、是否 robust 的关键。5.1 依赖安装的“静默”与“重启”难题坑点1静默安装参数不统一。不同厂商的安装包静默参数可能不同。VC Redist 通常用/install /quiet /norestart.NET 安装器用/install /quiet /norestart但有些老版本的 .NET Framework 可能用/q。Java JRE 的.msi包则用/quiet。务必查阅你所使用的特定依赖包的官方文档或通过安装包.exe /?查看命令行帮助。坑点2安装后需要重启。某些系统级组件如某些旧版本的 .NET Framework安装后可能要求重启。虽然我们加了/norestart参数但系统可能仍会标记“挂起的重启”。一个处理方法是在安装完所有组件后通过[Code]节检查是否需要重启并提示用户。[Code] procedure CurStepChanged(CurStep: TSetupStep); begin if CurStep ssPostInstall then begin // 检查是否需要重启 if IsPendingReboot then begin MsgBox(‘安装完成。某些更改需要重启计算机才能生效。建议您重启电脑。’, mbInformation, MB_OK); end; end; end; function IsPendingReboot: Boolean; begin // 检查常见的“挂起重启”注册表标志 Result : (RegKeyExists(HKLM, ‘SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations’)) or (RegValueExists(HKLM, ‘SYSTEM\CurrentControlSet\Control\Session Manager’, ‘SetupExecute’)) or (RegValueExists(HKLM, ‘SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing’, ‘RebootPending’)); end;5.2 开机启动的路径与参数问题坑点3路径中的空格。如果你的安装路径或程序名包含空格例如C:\Program Files\My Tool\MyApp.exe直接将其写入注册表的Run项可能会导致启动失败。最佳实践是使用双引号包裹整个路径。Inno Setup 的常量{app}在解析时不会自动加引号所以我们需要手动处理。[Registry] Root: HKCU; Subkey: “SOFTWARE\Microsoft\Windows\CurrentVersion\Run”; ValueType: string; ValueName: “{#MyAppName}”; ValueData: “””{app}\MyApp.exe”””; Flags: uninsdeletevalue; Tasks: autostart注意ValueData中的”””{app}\MyApp.exe”””。外层的两个双引号是 Pascal 字符串的转义实际写入注册表的值会是”C:\Program Files\My Tool\MyApp.exe”。坑点4带参数启动。如果你的程序需要带参数启动例如MyApp.exe -minimized只需在ValueData中加上即可”””{app}\MyApp.exe”” -minimized”。5.3 版本管理与升级安装坑点5覆盖安装与旧版本清理。当用户安装新版本时默认行为是覆盖安装到同一目录。这通常没问题但有时旧版本可能遗留了一些不再需要的文件。你可以在[InstallDelete]节中指定在安装前删除某些旧文件或目录。更常见的需求是在安装新版本前自动结束旧版本正在运行的进程。[Code] function InitializeSetup(): Boolean; begin Result : True; // 尝试终止正在运行的旧版本进程 if not ShellExec(‘’, ‘taskkill.exe’, ‘/f /im MyApp.exe’, ‘’, SW_HIDE, ewWaitUntilTerminated, ExitCode) then begin // taskkill 可能失败例如进程不存在这通常是正常的可以记录日志但不要阻止安装 Log(‘尝试结束进程 MyApp.exe 时发生错误或进程不存在。’); end; end;5.4 自定义界面与安装前环境检测为了让安装包更友好我们可以进行前置环境检测。例如如果你的程序必须运行在 Windows 10 或更高版本或者必须要有管理员权限可以在脚本一开始就检查。[Code] function InitializeSetup(): Boolean; var Version: TWindowsVersion; begin Result : True; GetWindowsVersionEx(Version); // 检查 Windows 版本 if Version.Major 10 then begin MsgBox(‘本软件需要 Windows 10 或更高版本的操作系统。’, mbError, MB_OK); Result : False; Exit; end; // 检查是否以管理员身份运行对于需要安装服务的场景 if not IsAdminLoggedOn then begin if MsgBox(‘本安装程序需要管理员权限。是否继续’, mbConfirmation, MB_YESNO) IDYES then begin // 实际上Inno Setup 通过 PrivilegesRequiredadmin 会自己提权 // 这里只是示例更复杂的逻辑可以放在这里 end else begin Result : False; end; end; end;6. 完整脚本示例与编译测试将以上所有部分整合一个功能相对完整的 .iss 脚本示例如下。请根据你的实际项目路径和需求进行调整。; 定义常量便于维护 #define MyAppName “我的超级工具” #define MyAppVersion “1.0.0” #define MyAppPublisher “我的工作室” #define MyAppExeName “SuperTool.exe” #define MyAppId “{{你的GUID}” ; 使用工具生成唯一GUID [Setup] AppId{#MyAppId} AppName{#MyAppName} AppVersion{#MyAppVersion} AppPublisher{#MyAppPublisher} DefaultDirName{autopf}\{#MyAppName} DefaultGroupName{#MyAppName} ; 如果需要操作注册表自启动HKCU不需要admin或安装服务则可能需要admin权限 ; PrivilegesRequiredlowest ; PrivilegesRequiredOverridesAlloweddialog OutputDir.\Output OutputBaseFilename{#MyAppName}_Setup_v{#MyAppVersion} Compressionlzma2/ultra SolidCompressionyes WizardStylemodern ; 设置安装程序图标 SetupIconFile.\assets\setup.ico [Languages] Name: “chinesesimplified”; MessagesFile: “compiler:Languages\ChineseSimplified.isl” [Tasks] Name: “desktopicon”; Description: “创建桌面快捷方式”; GroupDescription: “附加图标:”; Flags: unchecked Name: “autostart”; Description: “开机时自动启动 {#MyAppName}”; GroupDescription: “其他任务:”; Flags: unchecked [Files] ; 主程序文件 Source: “.\build\Release\{#MyAppExeName}”; DestDir: “{app}”; Flags: ignoreversion ; 其他资源文件 Source: “.\build\Release\config.json”; DestDir: “{app}”; Flags: ignoreversion Source: “.\build\Release\*.dll”; DestDir: “{app}”; Flags: ignoreversion recursesubdirs createallsubdirs ; 依赖包安装后删除 Source: “.\deps\VC_redist.x64.exe”; DestDir: “{app}\deps”; Flags: ignoreversion deleteafterinstall Source: “.\deps\windowsdesktop-runtime-6.0.xx-win-x64.exe”; DestDir: “{app}\deps”; Flags: ignoreversion deleteafterinstall [Icons] Name: “{group}\{#MyAppName}”; Filename: “{app}\{#MyAppExeName}” Name: “{commondesktop}\{#MyAppName}”; Filename: “{app}\{#MyAppExeName}”; Tasks: desktopicon [Registry] ; 开机自启动用户可选 Root: HKCU; Subkey: “SOFTWARE\Microsoft\Windows\CurrentVersion\Run”; ValueType: string; ValueName: “{#MyAppName}”; ValueData: “””{app}\{#MyAppExeName}”””; Flags: uninsdeletevalue; Tasks: autostart [Run] ; 安装依赖条件执行 Filename: “{app}\deps\VC_redist.x64.exe”; Parameters: “/install /quiet /norestart”; StatusMsg: “正在安装 Microsoft Visual C 运行库…”; Check: not VCRedistInstalled Filename: “{app}\deps\windowsdesktop-runtime-6.0.xx-win-x64.exe”; Parameters: “/install /quiet /norestart”; StatusMsg: “正在安装 .NET 6 桌面运行时…”; Check: not DotNetRuntimeInstalled ; 安装完成后运行主程序 Filename: “{app}\{#MyAppExeName}”; Description: “启动 {#MyAppName}”; Flags: nowait postinstall skipifsilent [Code] function VCRedistInstalled: Boolean; var Version: String; begin Result : RegQueryStringValue(HKLM, ‘SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64’, ‘Version’, Version); // 更健壮的检查可以解析Version并与所需版本比较 if not Result then begin // 也可以检查其他可能的注册表路径 Result : RegKeyExists(HKLM, ‘SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64’); end; end; function DotNetRuntimeInstalled: Boolean; begin // 检查 .NET 6 运行时是否存在 Result : RegKeyExists(HKLM, ‘SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost’); if not Result then begin // 对于 x86 系统或安装在32位路径下的情况 Result : RegKeyExists(HKLM, ‘SOFTWARE\dotnet\Setup\InstalledVersions\x86\sharedhost’); end; end; procedure CurStepChanged(CurStep: TSetupStep); begin if CurStep ssPostInstall then begin // 可选安装完成后提示信息 // MsgBox(‘安装成功’, mbInformation, MB_OK); end; end;编译与测试将上述脚本保存为MyAppSetup.iss。准备好你的程序文件放在.\build\Release\、依赖包放在.\deps\和图标。打开 Inno Setup Compiler加载这个 .iss 文件。点击工具栏上的“编译”按钮或按 F9。编译成功后在.\Output目录下会生成我的超级工具_Setup_v1.0.0.exe。至关重要的步骤在一个干净的测试环境如虚拟机中运行这个安装包从头到尾走一遍流程测试所有功能安装路径选择、依赖是否静默安装、开机启动选项是否生效、程序能否正常启动、卸载是否干净。这是保证交付质量的最后一道也是最重要的一道关卡。通过以上步骤你就能打造出一个真正专业、用户友好的 Windows 程序安装包。它不仅能交付你的软件更能交付一份完整的、无忧的体验。记住安装包是你的软件给用户的第一印象一个可靠、智能的安装过程本身就是产品价值的一部分。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价