C# 使构建前和构建后事件脚本变得漂亮?

C# 使构建前和构建后事件脚本变得漂亮?,c#,visual-studio,visual-studio-2008,scripting,build,C#,Visual Studio,Visual Studio 2008,Scripting,Build,我有一些用于VisualStudio2008项目的构建前和构建后事件脚本(实际上主要是构建后事件脚本)。它们工作正常,因为它们功能正常,当Iexit 0生成成功时,以及当Iexit 1生成失败并出现错误时。然而,这个错误是巨大的,并且是这样的: The command "if Release == Debug goto Foo if Release == Release goto Bar exit 0 :Foo mkdir "abc" copy "$(TargetDir)file.dll" "

我有一些用于VisualStudio2008项目的构建前和构建后事件脚本(实际上主要是构建后事件脚本)。它们工作正常,因为它们功能正常,当I
exit 0
生成成功时,以及当I
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.
..\..\BuildScripts\PostBuild.bat $(ConfigurationName) $(ProjectName) "$(TargetDir)" "$(ProjectDir)"
@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
的各种参考?例如,以下是一个特定站点的部分示例:

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

是否有一种方法可以让Visual Studio抑制除了
echo
ed之外的所有脚本输出(因此使用
echo
仅输出您想要的内容才有意义),或者这些示例只是被误导了,他们没有意识到整个脚本总是被转储掉?

如果您将脚本放入批处理文件中,VS对此相当沉默。当您需要访问$(projectName)等时,您必须将它们作为参数传递给批处理文件。我查找了可能影响输出的设置,但找不到任何设置

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

@echo off
echo "I'm Gonna Fail"
exit 1
< > >代码>预生成事件>命令行< /C> > d:\Test.BAT,离开<代码>描述> />空>(描述是显示的而不是执行预构建事件)…在VS2008中,我在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):


OK——问题的核心似乎是VisualStudio C++和C语言构建引擎有很大不同。

C++构建引擎执行项目前或后生成事件“命令行”中指定的批代码,而不将实际代码倾倒到输出窗口;它只会抛出代码中的“代码>回声Eng/代码> ED,以及代码执行的命令发出的内容(如<代码>拷贝<代码>命令的2文件”。我在Web上看到的例子大概是针对VisualStudio的C++构建引擎,因为如果你把C语言的预编译或后生成的批处理代码放到C项目中的“事件命令行”框中,就不需要对C的构建引擎进行任何回应。

这是因为我使用的C.Sube构建引擎将所有的代码转储到输出窗口。Whatsmore,如果代码失败,它将包含在“错误列表”中出现的错误消息中的那个框中的整个代码块——C++构建引擎没有(稍后会更多)。 因此,我找到的最佳解决方案是尽量减少在C#project的构建前或构建后事件命令行框中放入的代码量。在执行时,放入其中的所有内容都将转储到输出窗口。减少代码量的最佳方法是使其只执行批处理文件,并将必要的参数传递给批处理文件的内容不会被批处理到输出窗口,但是(类似于C++命令引擎中的“命令行”中的代码)“代码>回声E/COD>批处理文件代码执行的命令的输出和输出将是一个控制C预编译或后编译脚本输出的好方法。C++构建引擎以C语言引擎处理批处理文件中的代码的方式处理命令行框中指定的代码;它不会将代码本身清除掉,只是代码的输出

基本上,如果你在VisualStudio中编译C++项目,你可以把所有批处理脚本放在“命令行”框中,它不会全部被倾倒到输出窗口。但是,如果编译一个C项目,我建议把你的批处理脚本放在一个单独的<代码> .BAT/COD>文件中,并用适当的论证调用那个文件。从编译前或编译后事件命令行框中选择ts。我最终得到的C#编译后事件命令行框如下所示:

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.
..\..\BuildScripts\PostBuild.bat $(ConfigurationName) $(ProjectName) "$(TargetDir)" "$(ProjectDir)"
@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
…我的PostBuild.bat文件如下所示:

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.
..\..\BuildScripts\PostBuild.bat $(ConfigurationName) $(ProjectName) "$(TargetDir)" "$(ProjectDir)"
@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
ed才会输出到输出窗口

<>最后,如上面所提到的,C和C++构建引擎在错误列表中出现错误消息时,也会输出不同的东西,当后生成处理失败(即批代码退出代码之外的代码> 0代码/代码>)。C++构建引擎似乎总是说:

Error result 1 returned from 'C:\Windows\system32\cmd.exe'.
然而,C#build引擎将在错误消息中包含构建前或构建后事件命令行框(以失败的为准)的全部内容,例如:

The command "..\..\BuildScripts\PostBuild.bat Release MyProject "C:\Development\MyProject\bin\" "C:\Development\MyProject\"" exited with code 1.
对于一条错误消息来说,这仍然有点言过其实,但要比将我们移动到批处理文件中的所有代码都包含在错误消息中更容易管理


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

@Jez您的答案很好,但我会改进批处理文件,如下所示: 使用%%1可以更容易地从参数中删除引号:

@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

@stijn好奇的是,我没有在我的输出中看到
执行预构建事件…
。你使用的是什么版本的Visual Studio?另外,你能粘贴“预构建事件命令行”窗口内容的全部内容吗?更新了答案。你能准确地在命令行中发布你所使用的内容吗?我尝试了一些方法,但我做不到t使其显示整个命令line@stijnAHHH…你的是C++构建,我正在构建一个C项目,它解释了为什么我没有看到<代码>执行预构建事件< /Cord>输出。我看到了第二个。我将尝试运行一个.b。