Reputation:
I am running a heat command as pre-build event in my installer.wixproj.
I want my dir
-parameter (HarvestPath
) to be the target directory of my included project reference.
Now inside my .wixproj-file I have
<PropertyGroup>
<HarvestPath Condition=" '$(HarvestPath)' == '' ">"@(ProjectReference.TargetDir)"</HarvestPath>
<DefineConstants>HarvestPath=$(HarvestPath)</DefineConstants>
</PropertyGroup>
<ProjectReference Include="..\..\NAME.csproj">
<Name>NAME</Name>
<Project>SOME_GUID</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
How can I access the target directory of the project reference?
"@(ProjectReference)"
only gives me the full path to its .csproj file and I can't find any documentation for that.
Upvotes: 3
Views: 1583
Reputation: 43400
I found a more robust way to do it, though it's a little complicated. I had to do it this way to support building on a TFS build server with a newer build template (GitTemplate.12.xaml) because:
OutputPath
specified in the project (e.g. bin\Release\AnyCPU), but writes to its own build outputs folder.IntermediateOutputPath
(e.g. obj\Release\AnyCPU), but does not copy dependencies there, which heat.exe needs.This works by finding where project outputs actually went (_GatheredProjectReferencePaths
), which wix2010.targets has conveniently obtained for us via the MSBuild task. It gathers the relevant info into an item collection (COMProjects
), which the HeatCOMProjects
target loops over.
You will need to replace "ACME.Core", "ACME.Data", etc. with the names of the code projects you are heating, and ensure that the WiX project references them. You will also need to make sure the HeatFile commands have the correct arguments, particularly DirectoryRefId
, which I think needs to point to where the DLLs will be installed on the target system.
<!-- 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" />
Upvotes: 1
Reputation:
Ok so I found a workaround in case anyone is interested.
I simply used "$(SolutionDir)\MY_PROJECT_FOLDER\MY_PROJECT_TARGET"
. It's not exactly what I aimed for but it works.
Upvotes: 2