如何在编译之前订购文件?

时间:2014-12-02 14:28:23

标签: msbuild wix tfsbuild

我使用_PublishedApplications在TFS Build Server中生成结构。在此之后,我使用WiX项目中的<HeatDirectory>来正确地收集_Pub既适用文件夹的内容。但我的问题是构建期间的顺序。

如果我在<HeatDirectory>内使用<Target Name="BeforeBuild">,则不包括复制到_PublishedApplications的二进制文件,因为在发布(文件复制)之前执行收获。

如果我将目标更改为BeforeCompile,则编译不成功,因为首先没有文件。以下是WiX项目的代码(相关部分):

  <ItemGroup>
    <Compile Include="Product.wxs" />
    <Compile Include="Autogenerated.wxs" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\SimpleProject\SimpleProject.csproj">
      <Name>SimpleProject</Name>
      <Project>{GUID}</Project>
      <Private>True</Private>
      <DoNotHarvest>True</DoNotHarvest>
      <RefProjectOutputGroups>Binaries</RefProjectOutputGroups>
      <RefTargetDir>INSTALLFOLDER</RefTargetDir>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" />
  <Target Name="BeforeCompile">
    <HeatDirectory OutputFile="Autogenerated.wxs" Directory="$(Sources)"
                   PreprocessorVariable="var.SimpleProject.TargetDir" 
                   AutogenerateGuids="true" SuppressRegistry="true"
                   ToolPath="$(WixToolPath)" DirectoryRefId="INSTALLFOLDER"
                   ComponentGroupName="ComponentGroup_Core" 
                   SuppressRootDirectory="true" />
  </Target>

问题

如何在将二进制文件复制到_PublishedApplications后执行收获?

2 个答案:

答案 0 :(得分:1)

我使用以下命令构建我的解决方案:

msbuild SimpleInstaller.sln /p:OutDir=C:\Temp\Output\ /v:diag > C:\Temp\Log.txt

这会将所有日志输出到文本文件。您可以改为使用MSBuild logger

然后我发现在构建C#项目时,调用文件 Microsoft.Common.targets 中的目标Compile。此目标的属性DependsOnTarget包含对目标BeforeCompile的引用。

我可以在我自己的C#项目中覆盖此目标BeforeCompile,只需在其末尾添加以下代码(文件 .csproj ):

  ...
  <Target Name="BeforeCompile">
    <!-- custom action. -->
  </Target>
</Project>

但问题是我的WiX项目无法覆盖BeforeCompile目标,因为此目标尚未针对WiX项目定义。您可以在 wix2010.targets 文件中查看此内容。目标Compile仅依赖于目标PrepareForBuildResolveWixExtensionReferencesGenerateCompileWithObjectPath

我的解决方案是确定BeforeCompile Harvest目标的替代方案。我的WiX项目( .wixproj )现在具有以下目标:

<Target Name="Harvest">
  <HeatDirectory OutputFile="Autogenerated.wxs" Directory="$(Sources)"
                 PreprocessorVariable="var.SimpleProject.TargetDir" 
                 AutogenerateGuids="true" SuppressRegistry="true"
                 ToolPath="$(WixToolPath)" DirectoryRefId="INSTALLFOLDER"
                 ComponentGroupName="ComponentGroup_Core" 
                 SuppressRootDirectory="true" />
</Target>

出现所有这个问题是因为我在解决方案中的第一个项目是WiX项目,然后才添加了C#项目。出于这个原因,BeforeBuild在其他一切之前被执行。

解决此问题的另一个解决方案是编辑解决方案文件( .sln )并将解决方案文件开头的WiX项目声明移动到所有项目声明的末尾(而不是结束)解决方案文件)。然后,在C#项目创建_PublishedApplications文件夹之后,将执行WiX项目的BeforeBuild

此手动编辑是必需的,因为如果您更改项目构建顺序,实际上您正在更改项目引用(至少在解决方案文件中),但在BeforeBuild之前仍然会调用目标ResolveProjectReferences它负责调用任何引用的构建。

这是应该在所有其他人之后的项目声明:

Project("GUID") = "SimpleInstaller", "SimpleInstaller\SimpleInstaller.wixproj", "GUID"
EndProject

我的建议仍然是使用Harvest目标,因为它与解决方案文件中的任何更改无关。

答案 1 :(得分:0)

您需要做的第一件事是将安装程序项目中的项目引用添加到应用程序项目中。这将强制应用程序构建并可用于安装程序项目。

如果您在VisualStudio下右键单击解决方案并单击&#34;项目构建顺序...&#34;,如果您需要更改所需的顺序,则可以验证项目的构建顺序配置项目依赖项。

然后在安装程序项目中执行以下操作:

    <PropertyGroup>
        <RootDir>{PATH TO _PublishedApplications FOLDER}</RootDir>
        <HarvestDirectoryNoLogo>true</HarvestDirectoryNoLogo>
        <HarvestDirectorySuppressAllWarnings>false</HarvestDirectorySuppressAllWarnings>
        <HarvestDirectoryTreatWarningsAsErrors>false</HarvestDirectoryTreatWarningsAsErrors>
        <HarvestDirectoryTreatSpecificWarningsAsErrors>
        </HarvestDirectoryTreatSpecificWarningsAsErrors>
        <HarvestDirectoryVerboseOutput>false</HarvestDirectoryVerboseOutput>
        <HarvestDirectoryAutogenerateGuids>false</HarvestDirectoryAutogenerateGuids>
        <HarvestDirectoryGenerateGuidsNow>true</HarvestDirectoryGenerateGuidsNow>
        <HarvestDirectorySuppressFragments>true</HarvestDirectorySuppressFragments>
        <HarvestDirectorySuppressUniqueIds>false</HarvestDirectorySuppressUniqueIds>
    </PropertyGroup>
    <Import Project="$(WixTargetsPath)" />
    <Target Name="BeforeBuild">
        <ItemGroup>
            <HarvestDirectory Include="$(RootDir)">
                <Transforms>
                </Transforms>
                <ComponentGroupName>MyComponent</ComponentGroupName>
                <DirectoryRefId>WebSiteRoot</DirectoryRefId>
                <PreprocessorVariable>var.RootDir</PreprocessorVariable>
                <SuppressCom>false</SuppressCom>
                <SuppressRegistry>false</SuppressRegistry>
                <SuppressRootDirectory>true</SuppressRootDirectory>
                <KeepEmptyDirectories>true</KeepEmptyDirectories>
            </HarvestDirectory>
        </ItemGroup>
        <HeatDirectory 
            NoLogo="$(HarvestDirectoryNoLogo)" 
            SuppressAllWarnings="$(HarvestDirectorySuppressAllWarnings)" 
            SuppressSpecificWarnings="$(HarvestDirectorySuppressSpecificWarnings)" 
            ToolPath="$(WixToolPath)" 
            TreatWarningsAsErrors="$(HarvestDirectoryTreatWarningsAsErrors)" 
            TreatSpecificWarningsAsErrors="$(HarvestDirectoryTreatSpecificWarningsAsErrors)" 
            VerboseOutput="$(HarvestDirectoryVerboseOutput)" 
            AutogenerateGuids="$(HarvestDirectoryAutogenerateGuids)" 
            GenerateGuidsNow="$(HarvestDirectoryGenerateGuidsNow)" 
            OutputFile="$(IntermediateOutputPath)_%(HarvestDirectory.Filename)_dir.wxs" 
            SuppressFragments="$(HarvestDirectorySuppressFragments)" 
            SuppressUniqueIds="$(HarvestDirectorySuppressUniqueIds)" 
            Transforms="%(HarvestDirectory.Transforms)" 
            Directory="@(HarvestDirectory)" 
            ComponentGroupName="%(HarvestDirectory.ComponentGroupName)" 
            DirectoryRefId="%(HarvestDirectory.DirectoryRefId)" 
            KeepEmptyDirectories="%(HarvestDirectory.KeepEmptyDirectories)" 
            PreprocessorVariable="%(HarvestDirectory.PreprocessorVariable)" 
            SuppressCom="%(HarvestDirectory.SuppressCom)" 
            SuppressRootDirectory="%(HarvestDirectory.SuppressRootDirectory)" 
            SuppressRegistry="%(HarvestDirectory.SuppressRegistry)" />
    </Target>
</Project>

我根据HeatDirectory Task的文档生成了此代码,并在实际项目中使用它。