I am trying to build multiple .sln files inside a batch file. Everything works great so far. I am trying to add a check inside the batch file, so if number of errors is greater than 0 then the batch file stops executing and doesn't build the next .sln files. How can I do that? Basically something like:
msbuild test.sln
(check if build error > 0
stop)
msbuild test2.sln
MSBUILD will set the ERRORLEVEL, so something along the lines of:
msbuild test.sln
IF NOT ERRORLEVEL 0 exit 1
Edit: Apparently it should be:
msbuild test.sln
IF ERRORLEVEL 1 exit 1
msbuild.exe test.sln
if errorlevel 1 goto :errors
msbuild.exe test2.sln
if errorlevel 1 goto :errors
:: ...
:: Everything was fine.
echo Build completed without errors.
goto :eof
:error
echo Build failed.
In my opinion it's much easier to use a custom msbuild file here and use the msbuild task with your set of solutions. See here for the details.
Related
Is there any way to execute multiple feature files within a project using specrun.exe
eg: I have a project Student, and I have the below feature files:
a.Maths
b.Biology
C.Chemistry
d.Physics.
Now I need to execute Maths and Physics together. How to do it?
For single feature file (Eg:Maths) the below command is working fine.
#pushd %~dp0
%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe "Student.csproj"
#if ERRORLEVEL 1 goto end
#cd ..\packages\SpecRun.Runner.*\tools
#set profile=%1
#if "%profile%" == "" set profile=Default
SpecRun.exe run %~dp0\%profile%.srprofile "/baseFolder:%~dp0\bin\Debug" /log:specrun.log %2 /filter:testpath:Feature:Maths %4 %5
:end
#popd
Finally, I got the answer.
we have to exclude the feature files which we don't want to run.
The command that worked fine for me is as below
SpecRun.exe run %~dp0\%profile%.srprofile "/baseFolder:%~dp0\bin\Debug" /log:specrun.log "/filter:!testpath:Feature:Biology& !testpath:Feature:Chemistry"
I have a VS2008 solution file named MySolution.sln containing three projects ProjectName1, ProjectName2, ProjectName3 and ProjectName4. I am using jenkins to build the solution(to built only ProjectName1/2/3 and not ProjectName4). Below is the batch which has been provided to jenkins.
The issue is whenever lets say, the statement "%VSDIR%\devenv.com" "MySolution.sln" /Build "Release|x64" /Project ProjectName1 failed to build the particular project my %errorlevel% is not updated to non negative integer (>0). Irrespective of pass/fail the %errorlevel% is always "0"
The way jenkins calls this is
cmd /c call C:\Users\John\AppData\Local\Temp\hudson343434346343.bat
Any ideas on this?
Batch script:
#ECHO OFF
set VSDIR=C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE
"%VSDIR%\devenv.com" "MySolution.sln" /Clean "Release|x64"
"%VSDIR%\devenv.com" "MySolution.sln" /Build "Release|x64" /Project ProjectName1
IF %ERRORLEVEL% EQU 0 (
"%VSDIR%\devenv.com" "MySolution.sln" /Build "Release|x64" /Project ProjectName2
IF %ERRORLEVEL% EQU 0 (
"%VSDIR%\devenv.com" "MySolution.sln" /Build "Release|x64" /Project ProjectName3
IF %ERRORLEVEL% EQU 0 (
) ELSE (
echo "Failed to build ProjectName3"
)
) ELSE (
echo "Failed to build ProjectName2"
)
) ELSE (
echo "Failed to build ProjectName1"
)
unset VSDIR
just use MSBuild plug-in. You are all set.
I have several suggestions to make this simpler and more reliable.
You do not need to do a separate call to devenv.com in order to do a /Clean. Simply replace the /Build command in subsequent devenv.com calls with /Rebuild, which will clean before building from scratch.
After each call to devenv.com immediately do:
if ERRORLEVEL 1 echo Error building Solution X & goto some-label
This will detect any ERRORLEVEL of 1 or higher. This approach will not require any parentheses or ELSE clauses, and avoid the need to nest the subsequent IF statements.
You can also build the 3 (out of 4) projects with a single devenv.com call. This would require you to specify a solution build configuration that excludes (skips) the fourth project. For example:
"%VSDIR%\devenv.com" "MySolution.sln" /Rebuild "Release-Jenkins|x64"
The above approach requires first loading the solution in the Visual Studio IDE, going into the Configuration Manager, and creating a new solution build configuration (based on a copy of the existing Release build configuration). Name the new solution build configuration Release-Jenkins (or whatever), then make sure the project you wish to exclude is unchecked for each of the variations of Win32/x64/AnyCPU. Also, be sure to UNCHECK the checkbox to Create new project configurations, as you do not require any new project configurations. Also create a corresponding solution build configuration for Debug builds, i.e. Debug-Jenkins.
The unset command works in bash, but not for cmd.exe shells. To undefine the variable, do:
set VSDIR=
with nothing following the = sign. Or even better, add the command SETLOCAL on its own line immediately after #ECHO OFF. The SETLOCAL statement will ensure any environment variable changes are discarded when the batch file exits.
When I build a Visual Studio 2010 project, I want to run unit tests with NUnit and display test results only when some tests have failed.
I have setup a post-build event in Visual Studio to call a batch file like below:
$(ProjectDir)RunUnitTest.bat "$(SolutionDir)packages\NUnit.Runners.2.6.0.12051\tools\nunit-console.exe" "$(TargetPath)"
Then in RunUnitTest.bat, I call nunit-console.exe and pass in the test project dll.
#echo off
REM runner is the full path to nunit-console.exe
set runner=%1
REM target is the full path to the dll containing unit tests
set target=%2
"%runner%" "%target%"
if errorlevel 1 goto failed
if errorlevel 0 goto passed
:failed
echo some tests failed
goto end
:passed
echo all tests passed
goto end
:end
echo on
After that, NUnit generates TestResult.xml containing test results, so how do I display it in user friendly way? It'll be the best if it displays inside Visual Studio, but other options are open too.
You might want to consider XSLT to perform a transformation and display the results from TestResult.xml.
I ended up using nunit-summary to generate all pass summary html reports and nunit-results to create failed test reports in html.
This approach is quiet easy to setup.
First, download nunit-summary and nunit-results from launchpad and put them in TestRunner folder under the test project.
Then, add a post-build event to call a batch file.
Lastly, add the batch file to TestRunner folder under test project. It should contain the following files at the least:
nunit-results.exe
nunit-results.tests.dll
nunit-results.tests.pdb
nunit-summary.exe
`nunit-core.dll
nunit.util.dll
RunUnitTests.bat
Post-build event for the project containing unit tests:
"$(ProjectDir)TestRunner\RunUnitTests.bat" "$(SolutionDir)packages\NUnit.Runners.2.6.0.12051\tools\nunit-console.exe" "$(TargetPath)" "$(TargetDir)"
Scripts in RunUnitTest.bat
REM This batch file does the followings:
REM 1. runs unit test with nunit-console.exe and produces a TestResult.xml
REM 2. if one or more tests failes, it calls unit-results.exe to convert TestResult.xml to
REM Usage: RunUnitTests.bat "path-to-nunit.exe" "path-to-test.dll" "path-to-output-folder"
#echo off
REM get input arguments
set runner=%1
set target=%2
set output=%3
REM remove double quotes
set runner=%runner:"=%
set target=%target:"=%
set output=%output:"=%
REM prepare and clean up TestResult folder
if not exist "%output%TestResults\nul" md "%output%TestResults"
del "%output%\TestResults\*.*" /q
"%runner%" "%target%"
if errorlevel 1 goto failed
if errorlevel 0 goto passed
:failed
echo some tests failed
"%~dp0nunit-results.exe" "%output%TestResult.xml"
"%output%TestResults\index.html"
exit 1
:passed
echo all tests passed
"%~dp0nunit-summary.exe" "%output%TestResult.xml" -out=TestResults\TestSummary.html
"%output%TestResults\TestSummary.html"
exit 0
Background: I have a post-build process that copies a file to another location. It looks like this:
copy $(TargetPath) "%programfiles%\mypath"
This step can fail if the another process is using the file. The step is not critical, so if possible I would like to ignore the failure. To do this I need the script to check to determine if the file is being used by another process.
Question: Is there a way of testing a file in a DOS script to determine if it is being used by another process?
You can see if the file exists, then rename a .dll/.exe even if it is being executed. Might want to do .pdb files, too.
IF EXIST $(TargetName).deleted del $(TargetName).deleted
IF EXIST $(TargetName).pdb.deleted del $(TargetName).pdb.deleted
IF EXIST "%programfiles%\mypath\$(TargetName)$(TargetExt)" REN "%programfiles%\mypath\$(TargetName)$(TargetExt)" $(TargetName).deleted
IF EXIST "%programfiles%\mypath\$(TargetName)$(TargetExt)" REN "%programfiles%\mypath\$(TargetName)$.pdb" $(TargetName).pdb.deleted
copy $(TargetPath) "%programfiles%\mypath"
Ok, so I needed to check the errorlevel after performing the copy, so that I could handle the exit properly. The solution is below:
copy $(TargetPath) "%programfiles%\mypath"
if errorlevel 1 goto BuildProcessFailed
goto BuildProcessOK
:BuildProcessFailed
echo BUILDPROCESS FAILED FOR PROJECT $(ProjectName)
goto ExitBuildProcess
:BuildProcessOK
echo BUILDPROCESS OK FOR PROJECT $(ProjectName)
:ExitBuildProcess
We have a Team City Build Server running and want to compile a Visual C++ project. So far this would be easy, since I've setup our Windows Build Agent with the Windows SDK, but we don't have a solution / project file.
The project files are instead created with CMake. CMake seems to be a little bit dumb (can't generate Solution when Visual Studio is not installed), but with some tricks, I could get it to do it. The solution can then be built with MSBuild.
And here comes the problem. For this to work automatically, I need to call the Windows SDK's SetEnv.cmd. And I can't seem to find it automatically. It's in the bin sub directory of the Windows SDK, but neither bin nor the root are in the path, and the %mssdk% environment variable is set by the SetEnv.cmd and is not available beforehand!
Adding the Windows SDK\bin dir to the PATH leads to SetEnv.cmd no longer working (exits with a message like The x86 compilers are not currently installed and Jump target Set_x86 not found.
The start menu link is calling the SetEnv.cmd with the Windows SDK dir as working directory instead. But if I add the root directory to the PATH, Bin\SetEnv.cmd is not available.
How can I find SetEnv.cmd automatically? Even setting an environment variable to the full path of the setenv.cmd doesn't work, and when I define %mssdk% as the sdk dir, then call %mssdk%\bin\SetEnv doesn't work as well. I also tried to define %mssdk%, then cd %mssdk%, then calling bin\SetEnv. Also compilers not found in all these cases. It also doesn't work if I manually cd to the root or bin dir on a command line and then call SetEnv.cmd...
The start menu link works fine though.
For the record, my solution for now, as strange as this is, is the following:
I created a MSBuild file that creates the solution file with CMake on the command line, then invokes the created solution with a MSBuild task. The MSBuild file can be easily built from TeamCity, though I needed some additional tricks to satisfy CMake's stupid looking for the compiler, though I won't invoke it thing. Not really satisfying, but it works.
My solution (sets %WindowsSdkPath%, so that SetEnv.cmd could be found under %WindowsSdkPath%Bin\):
#ECHO OFF
IF "%WindowsSdkVersion%"=="" (
CALL :SetWindowsSdkVersionHelper HKCU > nul 2>&1
IF ERRORLEVEL 1 CALL :SetWindowsSdkVersionHelper HKLM > nul 2>&1
IF ERRORLEVEL 1 GOTO ERROR_NOWSDK
)
CALL :SetWindowsSdkPathHelper > nul 2>&1
IF ERRORLEVEL 1 GOTO ERROR_NOWSDK
GOTO END
:SetWindowsSdkPathHelper
SET WindowsSdkPath=
FOR /F "tokens=1,2*" %%i in ('REG QUERY "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\%WindowsSdkVersion%" /V InstallationFolder') DO (
IF "%%i"=="InstallationFolder" (
SET "WindowsSdkPath=%%k"
)
)
IF "%WindowsSdkPath%"=="" EXIT /B 1
EXIT /B 0
:SetWindowsSdkVersion
CALL :GetWindowsSdkVersionHelper HKCU > nul 2>&1
IF ERRORLEVEL 1 CALL :GetWindowsSdkVersionHelper HKLM > nul 2>&1
IF ERRORLEVEL 1 EXIT /B 1
EXIT /B 0
:SetWindowsSdkVersionHelper
SET WindowsSdkVersion=
FOR /F "tokens=1,2*" %%i in ('REG QUERY "%1\SOFTWARE\Microsoft\Microsoft SDKs\Windows" /V "CurrentVersion"') DO (
IF "%%i"=="CurrentVersion" (
SET "WindowsSdkVersion=%%k"
)
)
IF "%WindowsSdkVersion%"=="" EXIT /B 1
EXIT /B 0
:ERROR_NOWSDK
ECHO The Windows SDK %WindowsSdkVersion% could not be found.
EXIT /B 1
:END
I was inspired for this by the SetEnv.cmd itself...
Mac, nice answer!
Now I would like to run msbuild with my project file. But before I should run SetEnv.Cmd - right?
So, here we go:
run_Macs_code.bat REM see above
call "%WindowsSdkPath%\bin\Setenv.cmd" /Release /x86 /xp
cd E:\client
msbuild client.proj
Now it's working :)