我找到了一种更强大的方法来做到这一点,尽管它有点复杂。我必须这样做以支持使用更新的构建模板(GitTemplate.12.xaml)在 TFS 构建服务器上构建,因为:
- 构建实际上并不写入
OutputPath
项目中指定的文件(例如 bin\Release\AnyCPU),而是写入它自己的构建输出文件夹。
- 构建确实写入
IntermediateOutputPath
(例如 obj\Release\AnyCPU),但不会在那里复制 heat.exe 需要的依赖项。
这通过查找项目输出的实际位置 ( _GatheredProjectReferencePaths
) 来工作,wix2010.targets 通过MSBuild 任务为我们方便地获得了该输出。它将相关信息收集到一个项目集合 ( COMProjects
) 中,HeatCOMProjects
目标循环遍历该项目集合。
您需要将“ACME.Core”、“ACME.Data”等替换为您正在加热的代码项目的名称,并确保 WiX 项目引用它们。您还需要确保 HeatFile 命令具有正确的参数,尤其是DirectoryRefId
,我认为这需要指向目标系统上将安装 DLL 的位置。
<!-- Find where the .dll and .tlb files of source projects were written to.
Can't rely on relative paths like "$(ProjectDir)..\..\ACME\ACME.Core\bin\$(ConfigurationName)\AnyCPU\ACME.Core.dll"
because some build templates don't actually write to OutputPath. Can't rely on the intermediate output path either
(obj\...) because Heat needs to be able to find dependencies of any DLLs given. -->
<Target Name="GetCOMProjects" DependsOnTargets="ResolveProjectReferences">
<ItemGroup>
<COMProjects Include="%(_GatheredProjectReferencePaths.Name)"
Condition="%(_GatheredProjectReferencePaths.Name) == 'ACME.Core' Or
%(_GatheredProjectReferencePaths.Name) == 'ACME.Data' ">
<Name>%(_GatheredProjectReferencePaths.Name)</Name>
<DLLPath>%(_GatheredProjectReferencePaths.FullPath)</DLLPath>
<TLBPath>$([System.IO.Path]::GetDirectoryName(%(_GatheredProjectReferencePaths.FullPath)))\%(_GatheredProjectReferencePaths.Filename).tlb</TLBPath>
</COMProjects>
</ItemGroup>
</Target>
<!-- Loop through each COMProjects item -->
<Target Name="HeatCOMProjects"
Inputs="%(COMProjects.DLLPath); %(COMProjects.TLBPath)"
Outputs="$(ProjectDir)%(COMProjects.Name).REGASM.wxs; $(ProjectDir)%(COMProjects.Name).REGTLB.wxs">
<HeatFile
ToolPath="$(WixToolPath)"
File="%(COMProjects.DLLPath)"
OutputFile="$(ProjectDir)%(COMProjects.Name).REGASM.wxs"
GenerateGuidsNow="true"
NoLogo="true"
ComponentGroupName="%(COMProjects.Name).REGASM"
DirectoryRefId="INSTALLDIR"
SuppressRootDirectory="true"
PreprocessorVariable="var.%(COMProjects.Name).TargetDir"
/>
<HeatFile
ToolPath="$(WixToolPath)"
File="%(COMProjects.TLBPath)"
OutputFile="$(ProjectDir)%(COMProjects.Name).REGTLB.wxs"
GenerateGuidsNow="true"
NoLogo="true"
ComponentGroupName="%(COMProjects.Name).REGTLB"
DirectoryRefId="INSTALLDIR"
SuppressRootDirectory="true"
PreprocessorVariable="var.%(COMProjects.Name).TargetDir"
/>
</Target>
<!-- Run Heat after building dependencies, but before building this project. -->
<Target Name="AfterResolveReferences" DependsOnTargets="GetCOMProjects; HeatCOMProjects" />