2

我在我的 installer.wixproj 中运行 heat 命令作为预构建事件。我希望我的dir-parameter ( HarvestPath) 成为我包含的项目参考的目标目录。

现在在我的 .wixproj 文件中,我有

<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>

如何访问项目引用的目标目录? "@(ProjectReference)"只给了我它的 .csproj 文件的完整路径,我找不到任何文档。

4

2 回答 2

2

好的,所以我找到了一个解决方法,以防有人感兴趣。我简单地使用了"$(SolutionDir)\MY_PROJECT_FOLDER\MY_PROJECT_TARGET". 这不完全是我的目标,但它有效。

于 2015-11-05T15:52:30.520 回答
1

我找到了一种更强大的方法来做到这一点,尽管它有点复杂。我必须这样做以支持使用更新的构建模板(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" />
于 2016-09-02T12:52:06.847 回答