4

我在 Visual Studio 2017 中有一个 C# 解决方案。我还有一个名为的批处理脚本foobar.bat,其中包含以下代码:

echo foobar : error 1: This is a test error.           

我的目标是在我构建特定项目时只让上面的测试错误消息出现在 Visual Studio 的错误列表中,并在它出现时停止构建。所以我把[path to script]\foobar.bat项目的构建后事件命令行放入然后构建。现在我在 Visual Studio 错误列表中 收到两条错误消息:

  1. The command "[path to script]\foobar.bat" exited with code -1.
  2. This is a test error.

在这种情况下,看到仅打印出我的构建后事件内容的第一条错误消息并没有帮助。我想抑制这个初始错误,以便只有我的自定义错误消息显示在错误列表中(或者至少将其更改为更有用的内容)。

这是我尝试过的:

  • 添加2>nul到我的批处理脚本的末尾没有效果。
  • 添加1>nul到我的批处理脚本的末尾会抑制这两个错误,这不是我想要的。
  • 添加&set errorlevel=0到我的批处理脚本的末尾没有效果。
  • 将该行添加exit 0到我的批处理脚本的末尾没有任何效果。
  • 将以下内容添加到我的 .csproj 文件(根据本文)的末尾会抑制第一个错误,但会使构建不再失败:
<Target
    Name="PostBuildEvent"
    Condition="'$(PostBuildEvent)'!=''"
    DependsOnTargets="$(PostBuildEventDependsOn)">
    <Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" IgnoreExitCode="true" />
</Target>

最后一个选项几乎让我得到了我想要的。但是,尽管有错误消息,但错误列表不会弹出,构建也不会失败。似乎任何会导致初始错误消息不出现的东西也会导致构建不再失败。是这样吗?或者有什么方法可以让构建失败而不显示初始错误消息?

4

2 回答 2

5

你可以做的是一起使用一个exec和一个error任务。

您需要编辑 .csproj 文件并在Target PostBuildEvent上面最后一个要点之后添加这些任务。

该解决方案的工作原理是获取 exec 任务的ExitCodeandOutput并使用它们触发错误任务,然后停止构建并记录消息。
Exec任务需要三个参数:

  • IgnoreStandardErrorWarningFormatIgnoreExitCode防止在此步骤记录错误
  • ConsoleToMsBuild获取输出需要参数(ConsoleToMSBuild在 VS 2017 中拼写)。

所以任务看起来像这样:

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="$(PostBuildEvent)" IgnoreStandardErrorWarningFormat="true" IgnoreExitCode="true" ConsoleToMsBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="OutputMessage" />
      <Output TaskParameter="ExitCode" PropertyName="ExitCode" />
    </Exec>
    <Error Text="$(OutputMessage)" Condition="$(ExitCode) == 10" />
    <!-- <Error Text="(optional text) : $(OutputMessage)" Condition="$(ExitCode) == 11" />
    <Error Text="(optional text) : $(OutputMessage)" Condition="$(ExitCode) == 12" /> -->
  </Target>

并编辑文件foobar.bat

echo foobar : error 1: This is a test error.
exit /b 10 <-- /b parameter needed if used in a .bat file

重要的部分是exit设置我们以后要使用的代码。

您可以Error对更多条件日志记录执行多个任务,或者仅按原样使用输出。

于 2019-04-27T16:27:24.690 回答
0

回复:在我的批处理脚本末尾添加 &set errorlevel=0 无效。

要忽略单个命令的退出代码,请使用 || 不是 & 或 &&。例如

Robocopy || set errorlevel=0

这仅表示 RoboCopy 以 errorlevel != 0 退出时,设置 errorlevel=0

“&&”在这个批处理文件中做了什么?] 1解释了这个以及更多

历史注释单与号例如

(prog1 arg1 arg2) & (cmd2 arg1 arg2 arg3)

运行这两个命令。它在 DOS 中不是很有用。在 Unix 中,它同时运行两个命令(2 个进程),等待两个命令完成。由于 DOS 不支持多进程,因此“&”只是顺序运行的语法糖。

单管 prog1 | prog2 在 DOS 中也受到同样的限制。在 Unix 中 prog1 在 stdout 上写入少量后,它可用于 prog2 在其 stdin 上。

在 DOS 中,这是

prog1 > tmpFile
prog2 < tmpFile

在许多情况下,这已经足够好了。在 write1Meg 的简单情况下 | head,(或更多) DOS 必须运行完成,head 可以在读取第 10 行后退出。

& 做什么?Unix 还支持 & 在命令行 prog1 的末尾 & 这会启动 prog1 并快速将控制权返回给控制台。

&& 和 || 仅当您知道退出代码 0 被视为“真”且非零被视为“假”时才有意义。还进行了短路评估,因此在检查第一个退出代码后的第二个命令。

prog1 && prog2

prog1 退出后,prog2 仅在 exitcode == 0 时运行

prog1 || prog2

prog1 退出后 prog2 仅在 exitcode != 0 时运行

于 2020-03-23T15:46:05.573 回答