繁体   English   中英

使构建前和构建后的事件脚本漂亮吗?

[英]Making pre- and post-build event scripts pretty?

我的 Visual Studio 2008 项目有一些相当大的构建前和构建后事件脚本(实际上它主要是构建后事件脚本)。 它们工作正常,因为它们 function 正确,当我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.

你明白了。 整个脚本总是作为错误描述的一部分被转储出去。 在构建过程中,整个脚本也在 Output window 中转储。 那么,为什么我在 web 上看到了在这些脚本中使用echo的各种参考资料? 例如,这是一个特定站点上的示例的一部分:

:BuildEventFailed
echo POSTBUILDSTEP for $(ProjectName) FAILED
exit 1
:BuildEventOK
echo POSTBUILDSTEP for $(ProjectName) COMPLETED OK

有没有办法让 Visual Studio 抑制所有脚本 output 除了echo ed(因此仅使用echo到 output 你想要的东西是有意义的),或者这些例子只是被误导了,他们没有意识到整个脚本总是被丢弃?

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

C++ 构建引擎执行项目的构建前或构建后事件“命令行”中指定的批处理代码,而无需将实际代码转储到 Output Z05B8C74CBD96FBF2DE4C1A352702FFF4; 它只是转储出代码echo的内容,以及代码执行的命令发出的内容(例如copy命令的“复制的 2 个文件”等)。 web are presumably intended for Visual Studio's C++ build engine, because there is no need really to echo anything with the C# build engine if you're putting your C# pre- or post-build batch code in the C# project's 'event command line' box .

这是因为我使用的 C# 构建引擎确实将该框中的所有代码转储到 Output window。 更重要的是,如果代码失败,它会在将出现在“错误列表”中的错误消息中包含该框中的整个代码块 - C++ 构建引擎不会(稍后会详细介绍)。

因此,我发现的最佳解决方案是尽量减少您在 C# 项目的构建前或构建后事件命令行框中输入的代码量。 您放入其中的所有内容都将在执行时转储到 Output window 中。 最小化代码的最佳方法是让它只执行一个批处理文件,并将必要的 arguments 传递给批处理文件。 The contents of the batch file will NOT be dumped to the Output window, but (like with code in the 'Command Line' for the C++ build engine) echo output and output from commands the batch file code executes will be; 这是控制 C# 预构建或构建后脚本的 output 的好方法。 然后,C++ 构建引擎以与 C# 引擎处理批处理文件中的代码相同的方式处理“命令行”框中指定的代码; 它不会转储代码本身,只是代码的 output。

所以基本上,如果您在 Visual Studio 中编译 C++ 项目,您只需将所有批处理脚本放在“命令行”框中,它就不会全部转储到 Output Z05B8C74CBD96FBF2DE4C1A354 但是,如果编译 C# 项目,我建议将您的批处理脚本放在单独的.bat文件中,然后从构建前或构建后的事件命令行框中使用适当的 arguments 调用该文件。 我最终得到了我的 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

This controls the output much more neatly, and only things echo ed in this batch script will be output to the Output window.

最后,如上所述,C# 和 C++ 构建引擎也 output 出现在“错误列表”中的错误消息中的不同内容,当构建后处理失败时(即,批处理代码0 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.

对于单个错误消息仍然有点拗口,但比将我们移动到批处理文件中的所有代码都包含在错误消息中更易于管理!

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

如果你把你的脚本放在一个批处理文件中,VS 会对此保持沉默。 当您需要访问 $(projectName) 等时,您必须将它们作为参数传递给批处理文件。 我寻找可能影响 output 的设置,但找不到任何设置。

使用此批处理文件 (d:\test.bat) 进行测试; 甚至不需要@echo off

@echo off
echo "I'm Gonna Fail"
exit 1

Pre-Build Event->Command Line设置为d:\test.bat ,将Description留空(描述是显示的内容,而不是Performing Pre-Build Event...。在 VS2008 中,我在构建 output window 中得到了这个C++项目:

Performing Pre-Build Event...
"I'm Gonna Fail"
Project : error PRJ0002 : Error result 1 returned from 'C:\Windows\system32\cmd.exe'.

对于 C# 项目,将改为显示( MSBuild verbosity设置为normal ):

Target PreBuildEvent:
  d:\test.bat
  "I'm gonna fail"
  Microsoft.Common.targets(895,9) error MSB3073: The command "d:\test.bat" exited with code 1.

@Jez你的回答很好,但我会改进批处理文件如下:通过使用 %~1 它将更容易地从 args 中删除引号:

@echo off
if "%~1"=="" (set ErrorMessage=Parameter 1 missing. It has to be the Config name. & GOTO :EndError)
if "%~2"=="" (set ErrorMessage=Parameter 2 missing. It has to be the Project name. & GOTO :EndError)
if "%~3"=="" (set ErrorMessage=Parameter 3 missing. It has to be the Targetdir. & GOTO :EndError)
if "%~4"=="" (set ErrorMessage=Parameter 4 missing. It has to be the Projectdir. & GOTO :EndError)

cd /D "%~dp0"  &:: setting current directory to there where the batchfile is.

:: With ~ the quotes are removed
set _configName=%~1 
set _projectName=%~2
set _targetDir=%~3
set _projectDir=%~4
set _outDir=%~5

rd Plugins\%_projectName% /S /Q
if errorlevel 1 (set ErrorMessage=remove directory failed!!. & GOTO :EndError)
md Plugins\%_projectName%
if errorlevel 1 (set ErrorMessage=make directory failed!!. & GOTO :EndError)
xcopy %_targetDir%* Plugins\%_projectName% /E /Q
if errorlevel 1 (set ErrorMessage=Copy failed!!. & GOTO :EndError)

exit 0

:EndError
echo --! Error in %~nx0 !-- 
echo %ErrorMessage%
pause
exit 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM