MSBuild 执行任务而不阻塞

标签 msbuild

有人碰巧知道一个可以防止此 MSBuild 任务阻塞的技巧吗?我真的只是希望资源管理器打开并且构建脚本继续运行。目前它会阻塞 Exec 任务,直到资源管理器窗口关闭。

<Target Name="OpenExplorer">
    <Exec Command='explorer.exe "$(DestinationDir)"' IgnoreExitCode="true" />
</Target>

谢谢!

编辑:我希望避免为此创建自定义任务。也许存在一些可以内联放置在 Command 中的命令行魔法?

最佳答案

这是一种仅使用 msbuild 和内联任务异步执行流程的简单方法。这仅适用于 MSBuild V4.0 及更高版本(上帝保佑 MSBuild 人员添加此功能!)。您不需要任何外部扩展包。

实际上,我们正在采用上面建议的代码并将其放入内联任务中。请随意修改代码以满足您的需求。

此解决方案的要点在于,它让您无需为自定义任务创建单独的 dll 而烦恼即可实现结果。扩展包中的实现肯定更加可靠,但这是解决此问题的一种快速但肮脏的方法。您还可以准确地自定义您希望其运行的方式。

  <!--Launch a Process in Parallel-->
  <UsingTask TaskName="ExecAsync" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <!--The file path is the full path to the executable file to run-->
      <FilePath ParameterType="System.String" Required="true" />
      <!--The arguments should contain all the command line arguments that need to be sent to the application-->
      <Arguments ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Code Type="Fragment" Language="cs">
        <![CDATA[
  string name = System.IO.Path.GetFileNameWithoutExtension(FilePath);
  Log.LogMessage("Starting {0}...", name);        
  System.Diagnostics.ProcessStartInfo processStartInfo = new System.Diagnostics.ProcessStartInfo(FilePath, Arguments);
  processStartInfo.UseShellExecute = true;
  System.Diagnostics.Process.Start(processStartInfo);
  Log.LogMessage("Finished running process {0}.", name);
  ]]>
      </Code>
    </Task>
  </UsingTask>

然后,您可以按照以下方式从普通脚本中调用 ExecAsync 任务。注意:我的下面的脚本用于收集应用程序的代码覆盖率。

<!--Start listening for coverage data:-->
<Message Text="Starting to listen for coverage..."/>
<ExecAsync FilePath='$(VSPerfCmdExePath)' Arguments='/start:coverage /output:"$(CoverageFilePath)"' ContinueOnError='true'/>
<Message Text="Listening for coverage..."/>

<!--Start App with Coverage:-->
<Message Text="Starting App..."/>
<Exec Command='"$(AppCoverageLatestExePath)"' ContinueOnError='true' WorkingDirectory='$(AppCoverageLatestFolder)'/>
<Message Text="App shut down."/>

<!--Stop gathering coverage results:-->
<Message Text="Stopping listening for coverage..."/>
<Exec Command='"$(VSPerfCmdExePath)" /shutdown'/>
<Message Text="Coverage shut down."/>

以下是对那里发生的事情的描述:

  1. 首先,我关闭性能工具,以便它监听 覆盖范围。我使用 AsyncExec 任务来执行此操作,因为通常 在 MSBuild 中运行时工具会阻塞(请参阅 here )。
  2. 接下来,我们开始我们想要收集报道的计划。
  3. 完成后我们会关闭覆盖工具。

关于MSBuild 执行任务而不阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2387456/

相关文章:

xml - 在构建解决方案时,如何让 MSBuild 任务生成 XML 文档?

build - 使用 msbuild 指定解决方案的项目文件

visual-studio - 如何取出 .sln- 或 .csprojfile 名称并将它们用作条件?

c# - 有没有办法覆盖 AssemblyInfo.cs 中的属性(例如 AssemblyVersionAttribute)?

c# - 在 MSBuild 任务中生成代码

jenkins - MSDeploy WMSVC 无法在 .net 环境中工作

c++ - 是否可以在没有 Visual Studio 的情况下使用 MSVC 进行编译?

c# - 如何在 Linux 上为 Windows 交叉编译 C# 项目?

.net - 如何在 csproj 中使用 dotnet-pack --version-suffix?

.net-core - dotfuscator 为 "dotnet build"或 "dotnet publish"- 无法加载 "FindProjectAssemblies"任务 PreEmptive.Dotfuscator.Internal.Tasks.dll