如何用WiX正确收割已发布的.NET 6 Windows服务项目?
解决方案
问题1:项目收割获取构建结果而非发布产物
默认启用EnableProjectHarvesting=true时,WiX会指向.NET项目的构建输出目录(如bin/Debug/net6.0-windows),该目录包含中间构建文件、类库DLL及冗余依赖。要获取干净的发布产物:
- 配置Windows服务项目的发布设置:选择「独立」部署模式,目标运行时设为x64,生成可执行文件而非类库DLL,发布目录仅包含运行必需文件。
- 禁用项目收割,改用
HarvestDirectory直接指向服务项目的发布输出目录。
问题2:正确配置HarvestDirectory路径
$(JenkinsLogCollector.TargetPath)是单个文件路径,不适合HarvestDirectory(需指向目录)。正确做法如下:
- 在WiX项目的
PropertyGroup中定义发布目录变量,路径根据服务项目的发布配置调整:
<PropertyGroup> <ServicePublishDir>$(SolutionDir)JenkinsLogCollector\bin\Release\net6.0-windows\publish\</ServicePublishDir> </PropertyGroup>
- 修改
HarvestDirectory引用该变量:
<HarvestDirectory Include="$(ServicePublishDir)"> <ComponentGroupName>LogCollectorFiles</ComponentGroupName> <DirectoryRefId>INSTALLFOLDER</DirectoryRefId> <SuppressRootDirectory>true</SuppressRootDirectory> </HarvestDirectory>
- 添加构建依赖,确保WiX构建前先完成服务项目发布:
<Target Name="PublishServiceProject" BeforeTargets="Harvest"> <MSBuild Projects="..\JenkinsLogCollector\JenkinsLogCollector.csproj" Targets="Publish" Properties="Configuration=Release;Platform=x64" /> </Target>
问题3:HarvestDirectory未生成组件组导致报错
报错The identifier 'WixComponentGroup:LogCollectorFiles' could not be found的核心原因是目标路径为空或配置错误,解决步骤:
- 验证
$(ServicePublishDir)指向的目录存在且包含文件,可手动检查或在Visual Studio中查看服务项目的发布输出。 - 确保
Package.wxs中定义了INSTALLFOLDER目录结构(WixUI_InstallDir依赖该目录):
<Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" /> </Directory> </Directory>
- 清理解决方案缓存后重新构建,或手动执行Heat命令验证收割逻辑:
heat dir "$(ServicePublishDir)" -cg LogCollectorFiles -dr INSTALLFOLDER -srd -out harvested.wxs
若命令能生成包含LogCollectorFiles组件组的wxs文件,说明配置无问题,仅需清理Visual Studio缓存。
完整WiX项目示例
<Project Sdk="WixToolset.Sdk/4.0.0"> <PropertyGroup> <OutputName>Jenkins Log Collector Installer</OutputName> <EnableProjectHarvesting>false</EnableProjectHarvesting> <HarvestFileSuppressUniqueIds>false</HarvestFileSuppressUniqueIds> <HarvestFileGenerateGuidsNow>true</HarvestFileGenerateGuidsNow> <ServicePublishDir>$(SolutionDir)JenkinsLogCollector\bin\Release\net6.0-windows\publish\</ServicePublishDir> </PropertyGroup> <Target Name="PublishServiceProject" BeforeTargets="Harvest"> <MSBuild Projects="..\JenkinsLogCollector\JenkinsLogCollector.csproj" Targets="Publish" Properties="Configuration=Release;Platform=x64" /> </Target> <ItemGroup> <Content Include="Variables.wxi" /> </ItemGroup> <ItemGroup> <HarvestDirectory Include="$(ServicePublishDir)"> <ComponentGroupName>LogCollectorFiles</ComponentGroupName> <DirectoryRefId>INSTALLFOLDER</DirectoryRefId> <SuppressRootDirectory>true</SuppressRootDirectory> </HarvestDirectory> <BindPath Include="$(ServicePublishDir)" /> </ItemGroup> <ItemGroup> <PackageReference Include="WixToolset.Heat" Version="4.0.0" /> <PackageReference Include="WixToolset.Netfx.wixext" Version="4.0.1" /> <PackageReference Include="WixToolset.UI.wixext" Version="4.0.0" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\JenkinsLogCollector\JenkinsLogCollector.csproj" /> </ItemGroup> </Project>
内容的提问来源于stack exchange,提问作者Haxton Fale
相关产品推荐
相关产品推荐

