如何为Windows平台.NET 5 Worker Service构建MSI安装包
我正在使用.NET 5和「Worker Service」模板构建一个小型Windows服务,已经添加了Hosting.WindowsService依赖以适配Windows系统运行环境。
目前我可以参照微软开发者博客的官方指南,通过Windows自带的sc.exe命令行工具正常执行服务的安装、卸载、启动和停止操作。
我希望构建一个MSI安装包用于分发程序,实现当前用户权限下的自动安装卸载,就像.NET Framework服务旧版的ServiceInstaller那样。
我在Stack Overflow上查阅了大量关于MSI打包工具的帖子,比如InstallShield、Advanced Installer,但想找更简单的方案。我之前用过Visual Studio Installer Project,它可以自动检测项目中的ServiceInstaller类完成服务安装,但.NET Core和.NET 5的服务构建逻辑不同,该工具已经不适用。
我还了解到部分开发者会给服务本身添加命令行参数,借助ServiceController和ServiceInstaller类实现自安装,但.NET 5中也无法使用这些类。
我可以选择将服务回退到.NET Framework 4.8实现需求,但我更倾向于不降级框架版本,请问有没有其他可行方案?
谢谢!
更新
我已经尝试使用InnoSetup,在Run和UninstallRun节点添加如下配置后可以正常运行,但我清楚这只是临时方案,请问有没有更优的实现方式?
[Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent Filename: {sys}\sc.exe; Parameters: "create TestService start= auto binPath= ""{app}\{#MyAppExeName}""" ; Flags: runhidden Filename: {sys}\sc.exe; Parameters: "description TestService ""My Test Service"""; Flags: runhidden [UninstallRun] Filename: {sys}\sc.exe; Parameters: "stop TestService" ; Flags: runhidden Filename: {sys}\sc.exe; Parameters: "delete TestService" ; Flags: runhidden
以下是三种无需降级.NET框架的可行方案,按正式程度排序:
方案1:使用Wix Toolset生成原生MSI(推荐用于正式分发)
Wix是微软官方推荐的MSI打包工具,3.11及以上版本原生支持.NET Core/.NET 5+服务的安装配置,完全不需要调用sc.exe,内置回滚机制,安装出错时会自动清理已创建的服务、文件等资源,不会残留无效配置。
操作步骤:
- 安装对应版本的Wix Toolset和Visual Studio扩展
- 新建Wix Setup项目,引用Worker Service项目的输出
- 在配置文件中使用内置的
ServiceInstall和ServiceControl元素即可完成服务的安装、启动、停止、卸载配置,还支持自定义服务启动类型、依赖项、错误恢复策略等参数
示例配置片段:
<ServiceInstall Id="TestServiceInstall" Type="ownProcess" Vital="yes" Name="TestService" DisplayName="My Test Service" Description="My Test Service Description" Start="auto" Account="LocalSystem" ErrorControl="normal" /> <ServiceControl Id="TestServiceControl" Name="TestService" Stop="both" Remove="uninstall" Start="install" Wait="yes" />
方案2:使用Advanced Installer免费版(低代码首选)
如果不想学习Wix的配置语法,可以用Advanced Installer的免费版,它已经原生适配.NET Core/.NET 5+的Worker Service项目:
- 导入你的服务项目输出后,工具会自动识别Windows服务类型
- 可视化配置服务参数,点几下即可生成标准MSI安装包,完全不需要手动写配置
- 免费版的功能完全满足小型服务的分发需求
方案3:实现服务自安装
你提到.NET 5无法使用ServiceController和ServiceInstaller是因为没有安装对应Nuget包,只要安装System.ServiceProcess.ServiceController包即可使用这两个类:
- 给你的Worker Service添加
--install/--uninstall命令行参数 - 在参数对应的逻辑中调用相关类完成服务的创建、删除、启动、停止操作
- 运行时需要管理员权限,和安装包的权限要求一致
注意事项
Windows系统的服务安装本身就要求管理员权限,不存在普通用户权限下安装系统服务的方案,这个是系统安全机制,所有工具都无法绕过。
你当前使用的InnoSetup调用sc.exe的方案也可以正常使用,唯一缺点是没有自动回滚机制,安装过程出错时可能会残留无效的服务条目,适合个人使用,正式分发更推荐前两种方案。
内容的提问来源于stack exchange,提问作者Simon

