Visual Studio:多个后置构建命令?

112

Visual Studio 2008可以让我声明一个命令,并将其附加到项目的post-build事件上。像很多开发者一样,我经常使用它将文件复制到应用程序输出目录。

我正在处理一个需要从两个不同位置复制文件到两个不同目标的项目。换句话说,我需要从同一个post-build事件中调用两个不同的xcopy命令。看起来post-build事件只能接受单个命令,如果我需要调用多个命令,就必须将命令放在*.bat文件中,并从post-build事件调用该文件。

这是正确的吗?还是有更简单的方法可以从post-build事件调用两个命令?

14个回答

130
您可以输入任意数量的构建后命令,只需用换行符分隔即可。
以下是我的一个项目示例: Post Build Event Commandline

40
尽管我的命令在不同的行上,但它们被连在一起运行,就像它们在同一行上一样。 - Trevor
8
很遗憾,至少在VS2015中,如果其中一个中间命令失败了,它似乎不会报告错误……它将最后一个命令的结果报告为后期构建步骤的结果。 - Johannes S.
3
看起来这个方法在Visual Studio中可以工作,但如果你在TFS构建机上使用MsBuild则不被支持。MsBuild会去掉换行符并因错误语法而无法执行该命令。 - Jeff B
我尝试了以下两种方法: iisreset xcopy $(TargetDir)ApplicationMig.dll "C:\Program Files\myapi\ApplicationMig.dll" /y 但这导致出现错误 Exited with code 4. 是只有多个复制和xcopy命令才能以这种方式工作吗?如果将IIS重置命令单独放在预构建事件中,那么它可以正常工作。 - RBT
1
对于VS2019,您可以在每行末尾添加一个“&”符号,以便查看https://dev59.com/sWsz5IYBdhLWcg3wNU8R。 - Shane

121

重要提示:执行批处理文件时,必须使用"call"语句以便执行后续行。如果不使用"call",程序将进入.bat文件但不会返回到后续的行。与DOS提示符相同。

例如:

call MyBatch1.bat
call MyBatch2.bat

3
这个提示适用于grunt和npm命令,因为它们都通过批处理文件(grunt.cmd和npm.cmd)运行。 - Matt Varblow

22

还有一种选择:可以使用&&将命令分开。例如:

copy $(TargetPath) d:\folder1 && copy $(TargetPath) d:\folder2

这不完全和用新行分隔相同:使用&&,如果上一个命令失败了,则下一个命令将不会运行。

用换行符分隔更容易阅读,所以应该首选它。然而,我知道至少有一种情况下&&是有用的。这种情况是,当您使用属性表格在不同的机器上具有不同的后构建步骤时。VS 2008不允许直接在属性表中设置PostBuildStep,但您可以添加一个带有您的命令的用户宏,并从主项目设置中调用它。宏是单行的,因此您可以使用&&来有多个命令。


12

每个命令都应该在单独的一行上。但我发现,如果其中一个命令执行出错,则整个后构建过程将失败,因此您需要逐个尝试每个后构建命令以进行调试。


3
"xcopy /f"会显示完整的源文件名和目标文件名,在复制失败前会打印这些信息,这使得诊断多个xcopy命令比多个copy命令更容易。 - yoyo

10

在VS2017中,使用 & 或 && 或 ; 分隔命令是无效的。无法相信这么简单的功能在VS2017中不可用。Visual Studio尝试将后期构建事件窗口中的整个文本作为一个字符串执行。我现在的唯一选择是创建一个批处理脚本,但我并不特别喜欢。


1
在VS2017中,使用“&&”将命令分开对我有效。在VS2017编辑器中将每个命令指定到单独的行上并不适用于我。 - codesniffer

9

womp答案 的基础上,如果你有多个属性表需要在同一个构建事件中执行操作,可以按照以下方式链接命令:

%(Command)
echo foo

%(Command)会扩展为前一个命令的值。

个人认为,即使我当前没有继承命令,我也会对所有构建事件执行此操作,因为这可以确保如果以后添加属性表,就不会出现问题。


1
这同样适用于自定义构建步骤。此外,在链的任何位置执行“exit”批处理语句都会导致该链中止。确实,“exit 1”会导致构建失败,而“exit 0”仅会中止该步骤,构建将继续进行。 - Martin Connell

4
在 Visual Studio 2017 中,您可以这样做:
<PostBuildEvent>
    <Command>
        copy $(TargetPath) $(SolutionDIr)\bin1
        copy $(TargetPath) $(SolutionDIr)\bin2
    </Command>
</PostBuildEvent>

3
我编辑了.csproj文件,在我的两个后期生成事件命令周围添加了<Command></Command>。但似乎没有起作用。在Visual Studio的“生成事件”中查看时,这两个命令周围有<Command></Command>,但是构建出错并显示错误信息:The command "<Command xmlns="..">command1 command2</Command>" exitted with code 255. - Jimmy

3

womp提出的方法在Visual Studio 2015/2017(Windows)中可行,但在Visual Studio for Mac(Preview)中不起作用,似乎只执行第一个命令。 我发现在Visual Studio的Mac和Windows版本中都有效的唯一方法是链接两个MSBuild命令:

<Target Name="AfterResolveReferences">
<Exec Command="path\MyFirstCommand.exe -parameters" />
</Target>
<Target Name="MySecondCommand" AfterTargets="AfterResolveReferences" >
<Exec Command="path\MySecondCommand.exe -parameters" />
</Target>

上面的例子使用了"AfterResolveReferences"事件,但显然也适用于PostBuild事件。

2
这个问题没有很好的解决方案。调用这个想法会导致其他脚本运行。我注意到错误检测无法正常工作。 在FailMe.cmd中放入“exit /b 1”。 在构建后步骤中使用“call FailMe.cmd”。 注意,构建不会失败吗?我正在使用Visual Studio 2017构建C#项目。 现在尝试使用'FailMe.cmd',构建现在报告错误。 因此,如果错误报告很重要,您最好只使用单个脚本。

2

对于像我这样的白痴,有一个“下拉”按钮可以将命令编辑为多行文本。

输入图像描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接