对于我的Visual Studio 2008项目,我有一些适度的构建前和构建后事件脚本(实际上主要是构建后事件脚本)。它们工作正常,因为它们可以正常运行,当我exit 0构建成功时,当我exit 1构建失败时,出现错误。但是,该错误是巨大的,并且是这样的:

The command "if Release == Debug goto Foo
if Release == Release goto Bar
exit 0

:Foo
mkdir "abc"
copy "$(TargetDir)file.dll" "abc"
[...]
" exited with code 1.

你明白了。整个脚本始终作为错误描述的一部分转储出去。生成过程中,整个脚本也将转储到“输出”窗口中。那么,为什么我在网络上看到关于在这些脚本中使用echo的各种引用?例如,这是一个特定站点上的示例的一部分:
:BuildEventFailed
echo POSTBUILDSTEP for $(ProjectName) FAILED
exit 1
:BuildEventOK
echo POSTBUILDSTEP for $(ProjectName) COMPLETED OK

有没有一种方法可以使Visual Studio抑制除echo所编译的内容之外的所有脚本输出(因此,仅使用echo来输出所需的内容就可以了),或者这些示例只是被误导了,并且他们没有意识到整个例子脚本总是被丢弃吗?

最佳答案

好的-问题的核心似乎在于Visual Studio C++和C#构建引擎完全不同。

C++构建引擎执行项目的构建前或构建后事件“命令行”中指定的批处理代码,而无需将实际代码转储到“输出”窗口中;它只是转储出代码echo的内容,以及代码执行的命令所发送的内容(例如copy命令的“复制的2个文件”,等等。) Web大概是用于Visual Studio的C++构建引擎的,因为如果将C#构建前或构建后的批处理代码放在C#项目的“事件命令行”框中,则不需要真正使用C#构建引擎来回显任何内容。 。

这是因为我使用的C#构建引擎确实将该框中的所有代码都转储到了“输出”窗口中。而且,如果代码失败,它将在错误消息中的该框中包含整个代码块,该错误消息将显示在“错误列表”中-C++生成引擎不会(稍后会详细介绍)。

因此,我发现最好的解决方案是最小化您在C#项目的构建前或构建后事件命令行框中输入的代码量。您在其中放置的所有内容都会在执行时转储到“输出”窗口中。最小化代码的最佳方法是使其仅执行一个批处理文件,并将必要的参数传递给该批处理文件。批处理文件的内容不会被转储到“输出”窗口,而是(类似于C++构建引擎的“命令行”中的代码)echo输出和批处理文件代码执行的命令输出;这是控制C#生成前或生成后脚本的输出的好方法。然后,C++生成引擎将以与C#引擎对待批处理文件中的代码相同的方式来处理“命令行”框中指定的代码。它不会转储代码本身,而只会转储代码的输出。

因此,基本上,如果要在Visual Studio中编译C++项目,则只需将所有批处理脚本放在“命令行”框中,就不会将其全部转储到“输出”窗口中。但是,如果编译C#项目,我建议将批处理脚本放在单独的.bat文件中,并仅使用构建前或构建后事件命令行框中的适当参数调用该文件。我最终看到了C#构建后事件命令行框,如下所示:

..\..\BuildScripts\PostBuild.bat $(ConfigurationName) $(ProjectName) "$(TargetDir)" "$(ProjectDir)"

...以及我的PostBuild.bat文件如下所示:
@REM Store args...
set _configName=%1%
set _projectName=%2%

@REM Remove quotes from remaining args...
set _targetDir=###%3%###
set _targetDir=%_targetDir:"###=%
set _targetDir=%_targetDir:###"=%
set _targetDir=%_targetDir:###=%

set _projectDir=###%4%###
set _projectDir=%_projectDir:"###=%
set _projectDir=%_projectDir:###"=%
set _projectDir=%_projectDir:###=%

if %_configName% == Release goto StartProcessing
echo No post-build processing required.
exit 0

@REM Start post-build processing
:StartProcessing
echo Starting post-build processing.

@REM use input args to do batch script work, such as:
copy "%_targetDir%*.dll" "%_projectDir%..\..\..\..\..\CommonAssemblies"
if errorlevel 1 goto CopyFailure

@REM etc.

goto PostBuildSuccess

@REM Failure labels
:CopyFailure
echo Post-build processing for %_projectName% FAILED: Failed to copy file(s) to common assemblies directory!
exit 1

@REM Post-build success
:PostBuildSuccess
echo Post-build processing for %_projectName% completed OK.
exit 0

这样可以更加整洁地控制输出,并且只有此批处理脚本中echo编码的内容才会输出到“输出”窗口。

最后,如上所述,当生成后处理失败(即批处理代码以0以外的代码退出)时,C#和C++生成引擎还会在“错误列表”中显示的错误消息中输出不同的内容。 C++构建引擎似乎总是只说:
Error result 1 returned from 'C:\Windows\system32\cmd.exe'.

但是,C#构建引擎将在错误消息中包括构建前或构建后事件命令行框的全部内容(以失败者为准),例如:
The command "..\..\BuildScripts\PostBuild.bat Release MyProject "C:\Development\MyProject\bin\" "C:\Development\MyProject\"" exited with code 1.

对于单个错误消息来说还是有点麻烦,但是比将我们所有的代码移入错误消息中包含的批处理文件中而言,它更易于管理!

即使这样,能够自定义出现在错误列表中的错误消息以显示我定义的内容还是很不错的。我怀疑是否有可能,但是如果有人知道这样做的方法,请不要犹豫将其发布为评论!

10-05 20:43
查看更多