【问题标题】:Visual Studio add pre-build event that always runs (C# project)Visual Studio 添加始终运行的预构建事件(C# 项目)
【发布时间】:2015-05-09 02:21:59
【问题描述】:

在我的项目中,我正在运行一个外部工具来更新一些二进制文件。这些文件作为“内容”包含在项目中。

目前该工具设置为在 C# 项目属性中的“预构建事件”期间运行。不幸的是,这个事件只有在项目过期的情况下才会执行,这不是我需要的。

我通过在我的项目中始终使用“重建”而不是“构建”来解决这个问题,但这既乏味又缓慢。

无论项目是否是最新的,我都需要始终执行此工具。实际上,甚至在MSBuild 甚至在判断项目是否为最新之前,因为该工具修改了项目中包含的一些文件,从而影响了最新的检查结果。

有合适的方法吗?

【问题讨论】:

  • 不,在将项目加载到 IDE 时对其进行修改不会有好的结果。当然有更好的方法,您的问题对我们没有帮助。
  • @HansPassant 也许我过度设计了这个问题。归结为:有没有办法在构建之前始终运行命令?
  • 对于 C++ 项目,您可以使用具有 BeforeTargets="BuildGenerateSources" 属性的目标来执行此操作,对于 C#,您可以执行类似的操作,只需弄清楚您在构建中调用的众多目标中的哪一个将用于该 BeforeTargets 属性。运行详细的构建并检查输出或开始查看 Microsoft.CSharp.targets 左右。但是正如 Hans 所说:结果可能不是你所期望的
  • 当在 Visual Studio 的鼻子下更改磁盘上的源代码会导致各种有趣的行为,您需要关闭 HostCompiler 服务(这会降低 Visual Studio 的速度):@ 987654321@
  • 对于 C#,它将是 BuildDependsOn 组,msdn.microsoft.com/en-us/library/ms366724.aspx 或者您可以扩展解决方案本身:stackoverflow.com/a/5720489/736079(请参阅第二个答案,接受的答案不是您所追求的) .

标签: visual-studio-2013 msbuild pre-build-event


【解决方案1】:

这是解决方案。在您的项目文件中定义此属性:

<PropertyGroup>
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup> 

PreBuildStep 每次都会执行,无论项目是否是最新的。

Visual Studio 似乎绕过了对 MSBuild 的常规最新检查,并使用了某种更快的自定义检查,但具有破坏自定义构建目标的副作用。

【讨论】:

  • 更准确地说应该是&lt;PropertyGroup&gt; &lt;DisableFastUpToDateCheck&gt;true&lt;/DisableFastUpToDateCheck&gt; &lt;/PropertyGroup&gt;
  • 为什么接受的答案不是页面上的第一个答案?
  • 这也会触发构建,即使没有更改
【解决方案2】:

在项目级别,您有三个选项:

1) 预构建操作

<PropertyGroup>
  <PreBuildEvent>notepad.exe Foo.txt</PreBuildEvent>
</PropertyGroup>

2) 正常的BeforeBuild目标

<Target Name="BeforeBuild">
  <Exec Command="notepad.exe Foo.txt" />
</Target>

3) “附加”到“构建”目标(如 stijn 建议)

<Target Name="BeforeBuild2" BeforeTargets="Build">
  <Exec Command="notepad.exe Foo.txt" />
</Target>

实际上这个解决方案(在构建的情况下)将不起作用,因为 DependsOnTargetsBeforeTargets 之前执行。而正是在 DependsOnTargets 中,真正的(CoreBuild)位于:) 这就是他们发明“BeforeBuild”目标的原因;)


在这两种情况下,VS 检查是否有变化(文件是最新的)。如果没有任何改变,你为什么还要运行外部程序?如果这个程序在文件(例如“内容”)上工作,msbuild 和 VS 应该将文件检测为过时并处理构建。


不幸的是,IDE (Visual Studio) 有自己的方法来处理 msbuild 项目。主要机制是相同的,但是当决定构建或不构建什么项目,或者以什么顺序时...... VS 的行为完全不同。

您可以使用外部工具并针对您的解决方案或项目运行“msbuild”。这也将编译“正确的方式”并且二进制文件不会有所不同,但您将拥有 MsBuild 的全部功能和潜力

【讨论】:

  • 我需要运行外部程序,因为它将大量文件处理成单个二进制文件。将所有这些文件添加到 Visual Studio 项目中是不可行的,因此它们不在项目中。 MSBuild 对它们一无所知。外部工具有自己的最新检查机制,检查这些文件是否需要处理,但它首先需要运行,VS 不想配合。是不是问的太多了……
  • 你真的应该添加一个带有 BeforeTargets="BeforeBuild" 的 #4 示例。这很有帮助
  • 注意,如果有两个同名的目标,只会使用后者。因此,由于许多项目已经有了“BeforeBuild”目标,这可能会导致大量无声的问题。最好发明自己命名的目标并为其配备BeforeTargets="Build" 属性。
【解决方案3】:

还有一个额外的预构建事件,这里没有讨论。通常代码分析器使用它来检查代码分析器是否由 NuGet 下载。

因此,如果您想在代码分析器之前执行某些操作,则需要使用该目标。

您只需在 .csproj 文件中的 &lt;Project/&gt; 节点下添加 &lt;Target/&gt; 节点即可:

<Target Name="DownloadNugetPackages" BeforeTargets="PrepareForBuild">
    <Exec Command="notepad.exe Foo.txt"/>
</Target>

PrepareForBuild 事件将在 before 预构建事件之前运行。

【讨论】:

    【解决方案4】:

    这些解决方案都不适用于使用 Visual Studio for Mac 的我。 我想在构建项目之前运行一个 bash 脚本,但由于我使用的是 Xamarin,所以有些事情变得不正常了。我尝试了所有不同类型的目标,甚至尝试了项目选项中的 CustomCommands,但我仍然会遇到 MSbuild 只是自动运行或在构建之前没有真正运行的问题

    您可以在一个单独的项目中运行 PreBuild 事件,该项目在您的主项目之前编译。

    1. 创建一个新项目并将其命名为“PreBuildEvent”之类的名称
    2. 将如上所示的 MSbuild 目标/命令添加到每个属性组/构建配置的新 PreBuildEvent.csproj 文件中
    3. 在您最初执行 PreBuild 工作的项目中,添加对这个新项目的引用。
    4. 此新项目将首先构建,执行任何 PreBuild 事件,一旦构建此项目,它将启动原始项目的构建。这是因为当您添加对项目的引用时,Visual Studio 会确保以正确的顺序构建它们

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-28
      • 2016-05-21
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多