MSBuild 构建后

发布于 2024-10-05 03:19:47 字数 635 浏览 6 评论 0原文

我有一个 MSBuild 脚本,除了构建后步骤之外,它还可以执行我需要它执行的所有操作(请参阅我之前提出的问题:MSBuild 条件执行?)。

我想要做的是构建许多 csproj 文件,并选择性地执行构建后步骤(当且仅当项目已构建时)。我不想一直执行构建后步骤,否则最终输出的时间戳将被不必要地修改(并且它使构建过程无缘无故地非常耗时)。

在我的 MSBuild 脚本中,我的每个 csproj 文件都有类似以下内容的内容:

<Target Name="ProjectName">
   <MSBuild Projects="PathToProject" Properties="Configuration=$(buildtype)" />
</Target>

编辑: 我认为我真正想做的是检测每个项目的 CoreCompile 任务何时运行。是否有某种方法可以在条件下检查这一点?

有什么想法吗?

我是 MSBuild 的新手,所以也许我完全走错了路!

谢谢, 艾伦

I've got an MSBuild script that is just about doing everything that I need it to do apart from my post-build step (see a previous question that I asked: MSBuild conditional Exec?).

What I'm looking to do is build many csproj files and optionally perform post-build steps if and only if the project was built. I don't want to perform my post-build step all the time or else the timestamp on my final output will be modified unnecessarily (and it makes the build process very time consuming for no reason).

In my MSBuild script I've got something like the following for each of my csproj files:

<Target Name="ProjectName">
   <MSBuild Projects="PathToProject" Properties="Configuration=$(buildtype)" />
</Target>

Edit:
I think what I really want to do is detect when the CoreCompile task runs for each project. If there were some way to check for this in a condition?

Any ideas?

I'm new to MSBuild so maybe I'm on completely the wrong track!

Thanks,
Alan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黯然#的苍凉 2024-10-12 03:19:47

您还可以根据构建过程中选择的配置来执行此操作。对于 CI,您应该始终使用“发布”或“生产”(您可以定义自己的)。

<Exec Condition="'$(ConfigurationName)'=='Release'" Command="your command goes here ..."/>

You can also do it based on the configuration selected in your build process. For CI, you should always use "Release" or "Production" (you can define your own).

<Exec Condition="'$(ConfigurationName)'=='Release'" Command="your command goes here ..."/>
从来不烧饼 2024-10-12 03:19:47

经过多次寻找这个问题的简单解决方案后,我没有找到一个解决方案,最终提出了我自己的解决方案,该解决方案可行,但可能不是最好的解决方案。但是,我想与遇到同样问题的其他人分享它,以便您至少可以找到一个可行的解决方案,并希望为您省去很多麻烦。

回顾一下,我想做的是在项目构建后运行命令行工具,但前提是程序集已更新(即时间戳发生更改)。我不想将其放入每个项目的构建后部分,因为我只希望构建后发生在我们的构建服务器(而不是开发计算机)上。

我在主 .proj 文件中没有找到任何外部执行此操作的方法,并且最终更改了每个 .csproj 文件的构建后部分。但是,我在它前面添加了一个 if 条件,如下所示:

if '$(ExecuteCommand)' == 'true' command.exe

这意味着该命令永远不会在开发计算机上执行,但是当我从 .proj 文件调用构建时,我可以将该标志设置为 true,如下所示:

<!-- Define common properties -->
<PropertyGroup>
    <ExecuteCommand>true</ExecuteCommand>
</PropertyGroup>

<Target Name="YourTarget">
    <!-- Build project -->
    <MSBuild Projects="Path to project" Properties="ExecuteCommand=$(ExecuteCommand)" />
</Target>

正如我所说,我不认为这是最优雅的解决方案,但它确实有效,并且暂时对我来说足够了。然而,我仍然有兴趣了解实现这一目标的正确方法是什么,以便我可以改进我的脚本。

谢谢,
艾伦

After much searching for a simple solution to this problem I didn't find one and ended up coming up with a solution of my own that works but may not be the best solution. However, I wanted to share it with anyone else that is having the same problem so that you can at least have a working solution and hopefully saving you a lot of head banging.

To recap, what I wanted to do was run a command line tool after my project was built but only if the assembly was updated (i.e. the timestamp changed). I didn't want to put this into the post-build section of every project because I only wanted the post-build to happen on our build server (not development machines).

I didn't find any way of doing this externally in my main .proj file and did end up altering the post-build section of each .csproj file. However, I prefixed it with an if condition something like this:

if '$(ExecuteCommand)' == 'true' command.exe

This means that the command will never be executed on the development machine but when I invoke the build from my .proj file I can set that flag to true like this:

<!-- Define common properties -->
<PropertyGroup>
    <ExecuteCommand>true</ExecuteCommand>
</PropertyGroup>

<Target Name="YourTarget">
    <!-- Build project -->
    <MSBuild Projects="Path to project" Properties="ExecuteCommand=$(ExecuteCommand)" />
</Target>

As I said, I don't think it is the most graceful solution but it certainly works and will be sufficient for me for the time being. However, I'd still be interested to hear what the proper way of achieving this is so that I can improve my script.

Thanks,
Alan

风为裳 2024-10-12 03:19:47

如果您可以将以下内容添加到每个项目中:

<Target Name="DoStuffWithNewlyCompiledAssembly">
    <Exec Command="command.exe" />
</Target>

...那么您只需要添加一个属性:

<Target Name="Name">
  <MSBuild Projects="" Properties="TargetsTriggeredByCompilation=DoStuffWithNewlyCompiledAssembly" />
</Target>

这之所以有效,是因为 Microsoft 的聪明人在 CoreCompile 目标的末尾添加了以下行: Microsoft.[CSharp|VisualBasic][.Core].targets(文件名取决于语言和 MSBuild/Visual Studio 版本)。

<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''"/>

因此,如果您在 TargetsTriggeredByCompilation 属性中指定目标名称,则在 CoreCompile 运行时您的目标将运行,而在 CoreCompile 运行时您的目标将不会运行被跳过(例如,因为输出程序集相对于代码来说已经是最新的)。

If you can add the following to each of your projects:

<Target Name="DoStuffWithNewlyCompiledAssembly">
    <Exec Command="command.exe" />
</Target>

... then you only need to add a property:

<Target Name="Name">
  <MSBuild Projects="" Properties="TargetsTriggeredByCompilation=DoStuffWithNewlyCompiledAssembly" />
</Target>

This works because someone smart at Microsoft added the following line at the end of the CoreCompile target in Microsoft.[CSharp|VisualBasic][.Core].targets (the file name depends on the language and MSBuild/Visual Studio version).

<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''"/>

So if you specify a target name in the TargetsTriggeredByCompilation property, your target will run if CoreCompile runs-- and your target will not run if CoreCompile is skipped (e.g. because the output assembly is already up-to-date with respect to the code).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文