我有一个MSBuild文件,在编译应用程序之前操作AssemblyInfo文件。在构建结束时,它将还原AssemblyInfo文件。它通过备份文件,操作它,然后在构建时间之后恢复文件来完成此操作。
除非在构建期间发生错误,否则此工作相当不错。然后它不会恢复原始文件。有没有办法告诉MSBuild在构建结束时执行目标,无论它成功还是失败?
答案 0 :(得分:5)
根据您对原始问题的最后评论,我会采取另一种方法,并忘记您目前采取的方法。您应该知道您的版本信息不必在AssemblyInfo.cs文件中。它可以在任何代码文件中,只要你只有每个定义一次AssemblyVersion和AssemblyFileVersion属性。有了这样说,我会做的是遵循以下步骤:
让我们在#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)
如何改变问题:
作为进一步的改进,将Sayed的解决方案与我的解决方案结合起来,并从实际的AssemblyInfo.cs中删除版本信息,并使用已签入的VersionInfo.cs.template,在BeforeBuild中创建VersionInfo.cs。
答案 2 :(得分:0)
我从未使用它,但从文档中可以看出OnError Element对你想要实现的目标很有用。
导致一个或多个目标执行, 如果ContinueOnError属性是 错误的任务失败。