Advanced Installer实战:从MSI到Python打包的Windows交付指南
2026/9/7 2:41:45 网站建设 项目流程

简介:Advanced Installer 20.7.1是一款面向软件开发者与打包工程师的MSI安装包制作工具,图形化界面直观友好,可快速生成符合微软认证标准的安装包,并可自定义欢迎界面与安装过程界面。资源为完整压缩包,约161.36MB,内含2000个文件:以aip工程文件为核心,附有大量界面图标与样式图像,以及多类配置文件和说明文档,还包含msi成品示例与帮助手册,覆盖从工程搭建、资源编排到交付验证各环节。已有937人浏览学习,适合有一定打包基础、希望规范产出MSI安装包的开发人员。获取后可直接对照自带示例工程,快速掌握工程组织方式与多语言界面资源的实际用法;同时可参考模板配置欢迎界面、安装目录与卸载逻辑,减少从零摸索的时间成本,切实提升安装包制作效率。 这年头,写代码的人满大街都是,但能把安装包做得体面的,反而不多。我接手内部工具链维护之后,第一个被用户骂上门的需求,就是"这个软件怎么装不上""装了怎么没有快捷方式""卸载的时候怎么还有残留"。早年我也嫌打包麻烦,直接发压缩包,结果被折腾得够呛。后来换到 Advanced Installer 20.7.1 这款软件打包工具,才把Windows软件交付这条链路理顺。这篇东西就是我这两个多星期的实际使用记录,从功能拆解到完整打包流程,再到Python项目打包和几个工具之间的横向对比,适合所有在Windows平台上做桌面应用交付、却又没系统研究过安装包的开发者。

1. 软件交付最后一公里的麻烦,正好是Advanced Installer的用武之地

1.1 为什么zip压缩包撑不起正经交付

很多人觉得"把exe和dll塞进压缩包发给用户"就是交付,这个思路在小范围测试阶段没问题,一旦用户数量上来,各种环境差异就会被无限放大。最典型的几个问题:首先,大部分用户不会看"解压后运行里面的主程序.exe",他们只会双击压缩包里第一个看到的东西,报错之后就直接找客服。其次,zip包不带任何环境检测和依赖处理能力,目标机器缺个VC运行库、缺个.NET运行时,程序启动时弹一个莫名其妙的错误,用户根本不知道怎么处理。再者,没有卸载入口,用户想清理都没办法,残留文件和注册表项越积越多。

这些痛点本质上就是安装程序要解决的问题。一个合格的安装包至少要做三件事:把文件释放到指定目录、在开始菜单和桌面建立快捷方式、提供干净的卸载机制。做得更好一点的,还要处理注册表项、Windows服务、防火墙规则、环境变量、运行库检测这些额外资源。直接用脚本去写这些逻辑不是不行,但维护成本极高,尤其是要同时生成多种安装格式的时候。

1.2 MSI、EXE、MSIX三种安装形态的区别

Advanced Installer 20.7.1 的核心能力就是把这些交付形态统一在一个图形界面里。所谓的"打包",本质上就是选择输出格式的问题。MSI格式是Windows Installer的标准安装包,最大的好处是支持静默安装、支持组策略分发、支持公司域环境的批量部署,卸载信息统一写在系统里,用户可以走"设置-应用"正常卸载。EXE格式则是一个自解压引导程序,适合对安装过程做更多定制,比如在安装前检测Python解释器、下载依赖组件、弹出用户协议对话框。

我这次特别关注MSIX,因为它是微软这些年力推的新一代应用封装格式,支持增量更新、支持权限隔离,在Windows 10 1809之后的系统上体验很好,尤其是UWP和Win32应用都能覆盖。Advanced Installer 20.7.1对MSIX的构建支持已经非常成熟,可以直接把一个Win32程序包装成MSIX,而不需要去手写复杂清单文件。当然,MSIX对系统和证书的要求更高,普通个人软件用MSI或者EXE更务实一些。

2. Advanced Installer 20.7.1 的功能版图到底有多大

2.1 从项目向导到高级视图:图形界面比你想象的更深

第一次打开Advanced Installer的人,多半会被左侧那一长串功能面板吓到。其实不用慌,它的设计逻辑是分层级的:顶部的"项目向导"是最快速的上手路径,选好产品名称、公司名、版本号,下一步添加文件,再下一步配置快捷方式,整个过程五分钟就能生成一个可用的安装包。但真正让它和那些简易工具拉开差距的,是左侧的"高级视图"。

高级视图下,你能操作的东西包括但不限于:文件与目录的安装路径规划、注册表键值的写入与删除、环境变量的增改、Windows服务的安装配置、自定义对话框(比如安装路径选择页、许可协议页)、启动条件检测(比如操作系统版本、磁盘空间、是否安装了某个依赖)、以及数字签名证书的绑定。我用下来最顺手的是它的目录规则功能,可以按目标系统的Program Files、AppData、CommonAppData这些标准目录去映射,而不是死板地指定某个绝对路径。

2.2 升级与自动更新:软件装完不是结束,交付链路要继续

很多免费打包工具解决不了的一个问题,是"软件发布之后怎么升级"。Advanced Installer内置的Updater组件,允许你搭建自己的更新服务器,客户端安装包会在运行时检查更新服务器上的XML清单,发现新版本就弹出升级提示,然后增量下载新文件。这个功能对于没有独立运维团队的小产品来说,几乎是白嫖一个发布平台的体验。

我实测升级逻辑这块,它的版本规则比较明确:产品版本号、产品代码、升级代码三者之间的关系处理得好不好,直接影响"旧版本能不能被新版本替换"。在20.7.1版本里,当你创建一个新项目时,只要保持升级代码不变,并正确设置"使用该升级代码检查已安装的产品",生成的新MSI就能覆盖安装到旧版本目录。这里有个关键坑我后面会单独说:产品代码必须每次发布都换,升级代码则必须保持稳定。

2.3 平台支持与构建集成:不只是给安装工程师用

Advanced Installer 20.7.1的另一个优势是它可以嵌入到CI/CD流水线里,提供命令行构建接口,可以传入不同配置,实现"每次提交代码后自动编译并生成MSI并签名"的效果。这样安装包不再需要人工在本地点击构建,版本号也由构建系统统一注入。

支持的构建产物类型非常杂:既能构建传统桌面应用的MSI/MSIX,也能处理驱动包、Web应用部署包、Visual Studio扩展包。对我们这种管理一堆老项目的环境来说,最实用的其实是对WiX格式的兼容,可以打开.wxs源文件并在图形界面上编辑,这简直是维护WiX项目的救星,因为WiX项目手写XML的痛苦,谁维护谁知道。

3. 拿一个真实项目练手:从EXE到MSI的完整打包流程

3.1 打包前的准备:目录结构和参数的规划

我这次实战的目标是一个内部使用的WPF库存管理工具,编译产物是.NET 6.0框架下的exe加一堆dll。打包之前的第一步不是打开工具,而是先想清楚安装之后的目录结构。我的规划是:主程序文件安装到Program Files下的"Contoso/StockManager"目录,数据库链接配置放到CommonAppData下的共享目录,日志输出也走这个共享目录,这样卸载时不至于把用户数据一起清掉。

版本规划同样重要。我采用的是三等分版本号,主版本、次版本、修订号。项目属性里设定产品版本为1.2.0,升级代码在第一次创建项目时生成,之后保持不动,产品代码每次发布都用新的GUID。在Advanced Installer的项目属性页里,这些GUID都能一键重新生成,不用自己拿工具造。

3.2 分步操作:向导创建到最终构建

实际操作流程是这样的。新建项目时选择"MSI"类型,项目名称填"StockManager",厂商填"Contoso";然后切到"产品信息"页,填写产品版本1.2.0,升级代码留默认生成的GUID,产品代码在后面构建前重新生成一次。

第三步是"文件和文件夹"面板,我在Application的默认安装目录下建了一个子目录"StockManager",把编译好的整个bin输出目录拖进去,同时把外部的一个config.ini模板文件放到CommonAppData/Contoso/StockManager下面。这里有一个细节:如果配置文件要在安装时根据用户环境动态修改,可以使用"文件和文件夹"面板里的文本文件替换功能,用属性占位符替换掉配置里的机器名、安装路径之类的字段,而不是费劲去写自定义脚本。

第四步是"快捷方式"面板,勾选"开始菜单快捷方式"和"桌面快捷方式",都指向主程序StockManager.exe。右键桌面快捷方式还能自定义图标,我用的是Visual Studio资源文件里那个原始ico。

第五步是"启动条件"面板,添加一个".NET 6.0 Desktop Runtime"的检测条件。选择启动条件类型时可以选"软件组件",在列表里找对应运行时。Advanced Installer会生成条件语句,运行时检查不满足时弹出自定义提示,并可以把用户引导到官方运行库下载页面。

第六步回到"产品信息",点击"生成"按钮右侧的小箭头,确认勾选"在构建前重新生成产品代码",再点"构建"。输出目录下会生成一个StockManager.msi、一个StockManager.exe,以及一个带有.ais签名文件的构建产物文件夹。msi是标准格式,exe是添加了引导层的自解压版本,适合直接发给用户。

3.3 安装卸载验证:别跳过这一步

打包工具生成安装包的速度很快,但安装验证急不得。我为自己定了一个标准验证流程:先在装了干净的Windows 11虚拟机里执行MSI安装,检查开始菜单、桌面快捷方式、控制面板卸载入口、服务状态;然后执行卸载,再去Program Files和CommonAppData目录确认残留;最后再跑一遍静默安装,命令是msiexec /i StockManager.msi /quiet /norestart,确认在无人值守环境下不会卡在对话框上。

这个流程我连续跑了三遍,第一遍就发现了问题:卸载之后CommonAppData下的config.ini还留着。这其实是设计好的,因为配置文件里可能存了用户自己的连接串和偏好设置,属于用户数据,不应该跟着程序一起删。但如果有些临时文件也想卸载,就得在"卸载"面板里手动指定卸载时删除的额外文件或注册表键。这种细节,不做真实安装测试根本发现不了。

4. Python项目打包:Advanced Installer在解释型语言场景下的实践

4.1 两条技术路线的取舍

热搜词里有个高频问题:Python代码用什么打包工具最好。我的答案是分场景的,纯Python脚本交给用户跑,跟交付一个完整桌面应用,是完全不同的方案。Advanced Installer本身对Python支持不错,它可以在项目中直接集成Python解释器、检测Python运行时、打包Python脚本运行所需的依赖。但对于大多数业务系统来说,更稳妥的路线是先用PyInstaller把Python程序转成独立exe,再拿Advanced Installer对exe做系统层面封装。

为什么推荐两条腿走路?因为PyInstaller解决的是"把Python代码及其依赖模块打包成可执行文件",管的是Python运行时、第三方库、资源文件;Advanced Installer解决的是"把exe注册成Windows应用",管的是安装路径、快捷方式、启动条件、卸载信息、自动更新。两者的分工很清晰。

4.2 PyInstaller打包阶段的几个关键点

用PyInstaller生成独立exe时,有几个参数必须注意。我的建议是至少使用--noconsole消除黑框,--onefile生成单文件exe便于后续封装,--icon指定图标。如果程序依赖数据文件,比如模板Excel、配置文件、图标资源,一定要用--add-data "resources;resources"显式带上,否则运行时一定会报找不到文件的错误。另外别忽略隐藏导入,比如动态导入的模块、importlib加载的模块,PyInstaller是无法自动识别的,要用--hidden-import补上。

还有虚拟环境问题。我见过太多人在本机直接打包,结果PyInstaller把整个开发环境的包都收进去,产物体积动辄300MB以上。正确做法是创建一个干净的虚拟环境,只安装项目实际依赖的库,在虚拟环境里执行PyInstaller。这样打出来的exe体积会小很多,也能避免一些莫名其妙的库冲突。

4.3 把PyInstaller产物封装成MSI的实操

拿到PyInstaller生成的dist/main.exe之后,重新打开Advanced Installer,新建一个MSI项目。这一步其实比打包.NET程序还省事,因为不需要复制几十个dll,通常只有一个exe,顶多再带上--add-data引入的resources目录。

我这次封装的是一个基于Flask的本地服务工具,入口exe是一个后台服务而不是窗口程序。所以我在Advanced Installer里把安装类型设置成"服务安装",在"服务和驱动"面板注册对应启动方式,并指定服务名称、显示名称、启动参数。这种场景下,安装包的启动条件变成了检测Python是否在本地运行,其实不需要,PyInstaller打完的exe是完全独立的不依赖系统Python,检测条件就不需要了。

需要注意的坑,反而是杀毒软件误报。PyInstaller打出来的exe,在未签名情况下被Windows Defender标记的风险很高。解决办法是先完成代码签名再封装进MSI,或者退一步用Advanced Installer的"数字签名"向导给MSI本身签名。给MSI签名的好处是,安装时可以明显降低SmartScreen的拦截概率,卸载时也不会被安全软件拦。

5. 工具横向对比:Advanced Installer、Inno Setup、NSIS、InstallShield怎么选

5.1 核心参数对照表

做选型对比之前,先明确一点:没有哪个工具是绝对最好的,只有适合你团队场景的。以我接触这些工具的经验,把关键维度列成一张表格,会清晰很多。

工具授权模式操作方式支持格式学习曲线适合场景
Advanced Installer商业授权图形界面为主MSI/MSIX/EXE平坦需要MSI、自动更新、中文界面友好
Inno Setup免费开源脚本为主EXE中等个人免费软件、快速出EXE包
NSIS免费开源脚本为主EXE较陡高度定制安装界面和逻辑
InstallShield商业授权图形+脚本MSI/EXE较陡大型企业级商业软件
WiX免费开源XML源码MSI/MSIX陡峭需要MSI且要求完全可控

5.2 什么场景选什么工具,我的实际建议

如果是个人开源工具,不需要MSI分发,也不需要自动更新,Inno Setup是很不错的选择。它的Inno脚本语法读起来不费力,社区资源多,遇到问题搜一下基本都有答案。记得用起来的时候加上PrivilegesRequired=admin,避免出现权限不足导致文件写到Program Files失败的问题。

如果是企业内部的IT资产管理环境,需要配合组策略、SCCM做静默批量推送,那必须选带MSI输出能力的工具。免费方案里WiX是最正统的,但代价是你得跟XML搏斗;商业方案里Advanced Installer的图形界面能帮你省掉大部分写XML的功夫,遇到不会配的高级功能,图形面板上的下拉框总比记忆一堆元素标签来得靠谱。

NSIS相对更"程序员"一些,它的脚本语言接近汇编风格,配一个按钮重排都要写段逻辑。优势是生成的EXE体积小、加载快,适合做绿色软件的网络下载器。但如果你要为它写自动更新模块,工作量会明显大于用Advanced Installer自带Updater组件。

6. 我踩过的坑和排查思路,以及最终的配置建议

6.1 升级代码没管住,导致版本覆盖失败

打包发布最典型的一个坑,是升级代码和产品代码的关系搞错。项目上线后第一次发布1.1.0,生成的安装包里升级代码是GUID-A,产品代码是GUID-B。第二次发布了1.2.0,如果在创建项目时图省事点了"新建项目",而不是在旧项目基础上升级版本号,生成的产品代码变成GUID-C,升级代码也重新生成了GUID-D,这就意味着新MSI在用户机器上会被识别成完全独立的另一款软件,无法覆盖安装,用户机器上会同时存在两个"StockManager"。

排查方法很简单:打开MSI文件属性,在"关系"标签页能看到ProductCode、UpgradeCode和ProductVersion;或者直接在命令行执行msiexec /i StockManager.msi /l*v install.log,在日志里搜索Upgrade关键词,能看到它是否检测到已安装的产品。

修复方案也简单:保持升级代码始终不变,每次发布只修改产品版本号,并让产品代码重新生成。简单说,产品代码代表"这次安装的实体",升级代码代表"这条产品线"。

6.2 安装文件被占用,弹窗提示一堆红色警告

还有一次测试时,目标机器上已经运行着旧版本的程序,MSI安装过程到"停止服务"这一步直接失败,提示文件被占用。Advanced Installer 20.7.1对这种情况有处理选项,就是在"Windows Installer"设置里勾选"检测运行中的程序并自动关闭",同时可以配置"如果文件正在使用中,则系统重启后继续安装"。

更规范的做法是在"启动条件"里加一条进程检测,如果发现StockManager.exe正在运行,就弹出对话框提示用户先手动关闭,否则拒绝继续安装。我给内部产品最终选择了后者,原因是自动关进程可能造成用户未保存的数据丢失,这个风险不值得为省一步操作去承担。

6.3 我现在固定使用的一套配置清单

经过这些实测和踩坑,我最后固化了一套配置模板。项目属性里,"目标平台"选择x64,除非真的有32位兼容需求;启动条件固定包含操作系统版本检查、磁盘空间检查、管理员权限检查,其中管理员权限建议在"Prerequisites"里勾选"以管理员身份运行";卸载策略设置成"完全卸载",仅保留CommonAppData下用户配置目录。

构建参数上,我固定导出MSI和EXE两种产物,MSI用于域内分发,EXE用于面向用户的下载页。每次发布前跑一遍我前面说的虚拟机三连验证:安装、卸载、静默安装。签名证书绑定在构建服务器上,用命令行参数/sigcertauth指定证书指纹,这样打包流程全自动,不再依赖本地安装的证书。

这套流程跑顺之后,我现在每次发布工具链新版本,从构建到生成签名安装包,全程不需要打开Advanced Installer界面,都在CI脚本里一条命令完成。工具的价值,说到底不是让我们多点几下滑鼠,而是把交付这件事变得可预期、可重复、可复盘。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询