如何始终在MSBuild中执行目标

时间:2010-09-13 14:05:45

标签: msbuild

我有一个MSBuild文件,在编译应用程序之前操作AssemblyInfo文件。在构建结束时,它将还原AssemblyInfo文件。它通过备份文件,操作它,然后在构建时间之后恢复文件来完成此操作。

除非在构建期间发生错误,否则此工作相当不错。然后它不会恢复原始文件。有没有办法告诉MSBuild在构建结束时执行目标,无论它成功还是失败?

3 个答案:

答案 0 :(得分:5)

根据您对原始问题的最后评论,我会采取另一种方法,并忘记您目前采取的方法。您应该知道您的版本信息不必在AssemblyInfo.cs文件中。它可以在任何代码文件中,只要你只有每个定义一次AssemblyVersion和AssemblyFileVersion属性。有了这样说,我会做的是遵循以下步骤:

  1. 删除AssemblyVersion& AssemblyInfo.cs中的AssemblyFileVersion
  2. 创建一个新文件,在我的情况下将它命名为您想要的名称我将它放在Properties \ VersionInfo.cs中。 请勿将此文件添加到项目中。
  3. 编辑项目文件,将该文件包含在仅在您需要时编译的文件列表中
  4. 让我们在#3上稍微扩展一下。构建.NET项目时,项目本身就是一个MSBuild文件。在该文件中,您将找到一个声明为Compile的项目。这是将发送到编译器的文件列表。您可以动态地包含/排除该列表中的文件。在这种情况下,只有在构建服务器(或您定义的任何其他条件)上构建时,才要包含VersionInfo.cs文件。对于此示例,我将条件定义为项目是否在发布模式下构建。因此,对于Release模式,VersionInfo.cs将被发送到编译器,而不是其他版本。以下是VersionInfo.cs

    的内容

    <强> VersionInfo.cs

    [assembly: System.Reflection.AssemblyVersion("1.2.3.4")]
    [assembly: System.Reflection.AssemblyFileVersion("1.2.3.4")]
    

    为了将其挂钩到构建过程中,您必须编辑项目文件。在该文件中,您将找到一个元素(可能超过1,具体取决于项目类型)。您应该添加类似于以下内容的目标。

    <Target Name="BeforeCompile">
      <ItemGroup Condition=" '$(Configuration)'=='Release' ">
        <Compile Include="Properties\VersionInfo.cs" />
      </ItemGroup>
    </Target>
    

    我在这里所做的是定义一个目标,即BeforeCompile,它是一个众所周知的目标,你可以覆盖。有关其他类似目标,请参阅此MSDN article。基本上,这是一个在调用编译器之前始终会调用的目标。在此目标中,仅当Configuration属性设置为release时,才将VersionInfo.cs添加到Compile项。您可以将该属性定义为您想要的任何属性。例如,如果您将TFS作为构建服务器,则可以是

    <Target Name="BeforeCompile">
      <ItemGroup Condition=" '$(TeamFoundationServerUrl)'!='' ">
        <Compile Include="Properties\VersionInfo.cs" />
      </ItemGroup>
    </Target>
    

    因为我们知道TeamFoundationServerUrl仅在通过TFS构建时定义。

    如果您正构建命令行,那么就像这样

    <Target Name="BeforeCompile">
      <ItemGroup Condition=" '$(IncludeVersionInfo)'=='true' ">
        <Compile Include="Properties\VersionInfo.cs" />
      </ItemGroup>
    </Target>
    

    当您构建项目时,只需执行msbuild.exe YourProject.proj / p:IncludeVersion = true。注意:构建解决方案时这不起作用。

答案 1 :(得分:2)

如何改变问题:

  • 将一个“模板”AssemblyInfo.cs.template添加到版本控件中,该控件代表您的“理想”AssemblyInfo.cs,其中包含正则表达式挂钩
  • 在构建之前,将模板复制到真实并应用您的正则表达式
  • 为AssemblyInfo.cs添加某种subversion ignore(我不是svn专家,但我很确定有一种方法可以告诉它忽略某些文件)
  • 如果你的开发人员需要添加某种通常出现在AssemblyInfo.cs中的自定义(例如InternalsVisibleTo),那么让他们将它添加到不同的 .cs文件中已签到。

作为进一步的改进,将Sayed的解决方案与我的解决方案结合起来,并从实际的AssemblyInfo.cs中删除版本信息,并使用已签入的VersionInfo.cs.template,在BeforeBuild中创建VersionInfo.cs。

答案 2 :(得分:0)

我从未使用它,但从文档中可以看出OnError Element对你想要实现的目标很有用。

  

导致一个或多个目标执行,   如果ContinueOnError属性是   错误的任务失败。