I'm using team city to make an automatic deploy and MSBuild won't work...
In the build step the the command line parameters look like this:
ProjectName.deploy.cmd /y /M:https://[WebDeployUrl:8172]/MsDeploy.axd /u:username /p:password –allowUntrusted /A:basic
this works fine from my machine, but the build server fails with the following response:
[MSBuild output] MSBUILD : error MSB1001: Unknown switch.
[MSBuild output] Switch: /Y
Anyone has an idea about this?
This is a very old question, and the asker likely sorted out their issue long ago, but here goes anyways:
MSBuild tasks in TeamCity require a commandline that pertain to MSBuild.exe specifically, IIRC.
That is, TeamCity is executing MSBuild.exe with the parameters you've given it like so:
msbuild.exe ProjectName.deploy.cmd /y /M:https://[WebDeployURL]:8172]/MsDeploy.axd /u:username /p:password -allowUntrusted /A:basic
Of course, MSbuild has no idea what those switches are, nor would it be able to process 'ProjectName.deploy.cmd' as an MSBuild file.
Related
I'm trying to execute msbuild on Azure Devops. Because of that I cannot use the MSBuild task provided.
When I use a Command Line task the command is not recognised. On my local machine I load vcvarsall.bat before I use msbuild. But I've not been unable to work out how to obtain that path in Azure Devops. Doesn't appear to be a Develop Command Prompt task for Azue Devops either.
Any ideas on how I can use msbuild from a Command Line task or Batch Script task? Using their Hosted VS agent.
The best way to do this in a supported way is to use vswhere. The following bit of script will install vswhere (using chocolatey) and then query the installer registry where msbuild can be found. Replace -latest with a more specific version if you need that:
choco install vswhere
for /f "tokens=*" %%i in ('vswhere -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe -nologo') do set msbuildpath="%%i"
echo "##vso[task.setvariable variable=msbuildpath]%msbuildpath%"
This will save the path to msbuild to the environment variable %msbuildpath% as well as the pipeline variable (for this stage) $(msbuildpath).
You can then either use a second run commandline task and pass in $(msbuildpath) or you can simply call MsBuild from the same piece of script mentioned above by calling:
%msbuildpath%
This will make sure your script will remain working, even if Microsoft upgrades their images and moves some things around (which does happen).
You can also get vswhere using wget or invoke-webrequest -outfile from the following location:
https://github.com/Microsoft/vswhere/releases/latest/download/vswhere.exe
Other samples for vswhere syntax can be found on the project wiki, including the syntax for PowerShell.
If you use Hosted Agent 2017 you can run the msbuild.exe from the Command Line task in this way:
Command Line version 1:
Command Line version 2:
Results:
If you are interested in seeing how the built-in Microsoft task resolves the path, all the Azure Devops tasks are provided open-source. These are the path functions you probably care to review.
Here is the solution I came up with using only built-in pipeline tasks which makes the MSBuild bin directory available on the path environment variable.
Create a PowerShell task to generate an MSBuild project to capture and output to a file the variables you are interested in (ex. MSBuildBinPath)
PowerShell script
"<Project DefaultTargets=`"DetectMsBuild`">
<ItemGroup>
<OutFile Include=`"`$(MsBuildDetectionFile)`" />
<OutFile Condition=`"'`$(OutFile)' == ''`" Include=`"msbuildInfo.json`" />
</ItemGroup>
<Target Name=`"DetectMsBuild`">
<PropertyGroup>
<MsBuildPaths>
[{
`"Name`": `"BinPath`",
`"Value`": `"`$(MSBuildBinPath.Replace('\', '\\'))`"
}]
</MsBuildPaths>
</PropertyGroup>
<WriteLinesToFile
File=`"#(Outfile)`"
Lines=`"`$(MsBuildPaths)`"
Overwrite=`"true`"
Encoding=`"UTF-8`" />
</Target>
</Project>" | Out-File -FilePath "msbuilddetect.proj" -Encoding utf8
Set the working directory and any variables accordingly.
PowerShell task settings screenshot:
Create an MSBuild task to run the project file generated by the previous task. Ensure the MSBuild version is set to the version you want to use.
MSBuild task settings screenshot:
Last, create another PowerShell task that will parse the outputted JSON file of the extracted variables and sets environment variables accordingly.
PowerShell script
Write-Host "Current path: $($env.Path)`n`n"
$msBuildVariables = Get-Content -Path msbuildInfo.json | ConvertFrom-Json
$Path = "$($msBuildVariables[0].Value);$($env:Path)"
Write-Host "##vso[task.setvariable variable=Path;]$Path"
PowerShell task settings screenshot:
Here is a screenshot of the task order in the build pipeline.
Note: I'm using Mercurial as an example here, because that's what I'm trying to get to work with MSBuild right now.
But the problem is not limited to Mercurial, it happens with every external program that is somewhere in my %PATH% variable (I tried the same with PowerShell, for example).
So I didn't put the Mercurial tag on this question on purpose, because this is not about Mercurial!
What I actually want to do:
I want my build script to get the current revision number from my Mercurial repository and store it in a file.
The simplest way to do this from the command line is:
hg id -i >rev.txt
Mercurial is installed on my machine and the installation folder is in my %PATH% variable.
So I can run this line from anywhere on my machine (directly from the command line, or from a batch file), and it just works.
The problem occurs when I try to run this line from my build script.
I change the BeforeBuild (or AfterBuild) section of my .csproj file as follows:
<Target Name="AfterBuild">
<Exec Command="hg id -i >rev.txt"/>
</Target>
When I compile my solution with Visual Studio, it works and the rev.txt file is created in the folder where my .csproj is.
But when I compile the exact same solution from the command line with MSBuild, the build fails with the following error message:
The command "hg id -i >rev.txt" exited with code 9009.
I googled "msbuild code 9009" and found some solutions, but all of them propose to provide the full path to the executable.
When I do this, the build succeeds with MSBuild as well.
But this is not an acceptable solution for me, because I can't be sure that everyone using my project (including the build server) has installed Mercurial in the exact same folder.
That's exactly what %PATH% is for...
The same happens when I put the <Exec Command="... line directly into the build script.
If I specify the path to the executable, it works.
If I don't specify the path, it doesn't.
Is there any trick to make MSBuild execute programs in my %PATH% variable without specifying the complete folder?
EDIT:
#leppie:
Output redirection:
You mean the fact that I save the output of my command in a text file inside the command , instead of just running hg id -i as a command and using an output parameter or something like that to get the output?
Doesn't make any difference...the error is the same when I omit >rev.txt.
Command line args:
No, it throws the same error, even if I shorten the command to just hg (without any parameters).
Don't forget: if I run the exact same Exec command in the exact same .csproj file from Visual Studio, or if I just provide the path to the .exe file in the command, everything works.
So IMO output redirection and command line args can't be the problem.
Have you tried this extension pack for mercurial/msbuild?
http://msbuildhg.codeplex.com/documentation
Seems to have a task for returning revision id, which is what your trying to achieve no?
<HgVersion LocalPath="$(MSBuildProjectDirectory)" Timeout="5000">
<Output TaskParameter="Revision" PropertyName="AssemblyRevision" />
</HgVersion>
Okay, I found the solution.
I have to admit, it was a classic case of PEBKAC :-)
I'll explain it anyway, maybe it will help someone who made the same mistake:
Basically everything I have tried (plus what James Woolfenden suggested in his answer) would have been worked...if only the batch file that I use to run the build script wouldn't have looked like this:
path="%windir%\Microsoft.net\Framework\v4.0.30319"
msbuild build.proj
Yes, exactly.
I'm editing the %PATH% variable for the duration of this batch file, and I'm overwriting it with the path to MSBuild instead of just appending it.
So when my build script tries to call Mercurial, it can't find it anymore because its location is not in the %PATH% variable anymore.
No idea why I didn't see this before.
The correct way would be to append the MSBuild path, leaving the other paths intact:
path=%path%;%windir%\Microsoft.net\Framework\v4.0.30319
I have written a batch file, which when executed builds a visual studio solution. The solution comprises of few C# projects. I am using MSBuild utility for this. How can i stop the build from proceeding further when there are compilation errors in any of the projects?
Further how can i get the error messages and display them on command prompt?
There's no support for stop on first failure when building a visual studio solution.
You can workaround this by taking the following steps:
Set the environment variable msbuildemitsolution to 1 (set msbuildemitsolution=1);
Invoke MSBuild in order to generate a *.proj file from the target VS solution;
In the generated *.sln.proj file change RunEachTargetSeparately="true" in the target named Build to RunEachTargetSeparately="false";
Invoke MSBuild to build the updated *.sln.proj file.
This answer is based on Dan Moseley answer to a post on MSDN Forums.
It would be easier to give you an answer if you would have posted relevant parts of your batch file. Nevertheless, for your second part of the question, here is an example how I solved almost the same issue in one of our build scripts:
msbuild.exe /m /p:Configuration=Release /v:n theSolutionFile.sln >Build.log
if ERRORLEVEL 1 goto :showerror
find "0 Warn" Build.log >nul:
if ERRORLEVEL 1 goto :showerror
goto :EOF
:showerror
echo Build error occurred
exit %ERRORLEVEL%
I have a project that has a post-build event that xcopies a DLLs to a certain directory:
xcopy "$(TargetDir)$(TargetName).dll" "$(SolutionDir)..\UdpLocationService\bin\Plugins\" /d /y
xcopy "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)..\UdpLocationService\bin\Plugins\" /d /y
However, I have CruiseControl.NET set up as a build server and MSBuild is failing on building that project due to this xcopy post-build event:
MSB3073: The command "xcopy "C:\Build\Services\Windows\VehicleServer\Plugins\Payload\bin\Debug\Payload.dll" "*Undefined*..\UdpLocationService\bin\Plugins\" /d /y xcopy "C:\Build\Services\Windows\VehicleServer\Plugins\Payload\bin\Debug\Payload.pdb" "*Undefined*..\UdpLocationService\bin\Plugins\" /d /y" exited with code 4. in Microsoft.Common.targets(3397, 13)
Any suggestions to get this fixed?
I just ran into the same problem with TeamCity.
The issue here is the $(SolutionDir) property in your build file. You haven't defined it in your call to MsBuild (this is why you see the word undefined in your output).
Call msbuild with the property set, like this:
msbuild myproject.csproj /property:SolutionDir="solution directory"\
Where "solution directory" is the directory containing your solution file. Note the trailing slash, you'll need that to make sure the path is correctly formed.
I fixed this for problems with the Microsoft.SqlServer.Compact nuget package (which adds a similar post-build script), by adding:
<SolutionDir Condition="'$(SolutionDir)'=='' or '$(SolutionDir)'=='*Undefined*'">..\</SolutionDir>
right above the <PostBuildEvent>. You'll want to adjust the relative path to match your project layout.
Follow these steps:
Unload your project file (e.g. *.csproj)
Open your project file for editing
Find the AfterBuild target
Separate out the two invocations of XCopy into two distinct Exec tasks
Save your changes and Reload your project file
I am trying to run a command line action in my Team Build (MSBuild).
When I run it on the command line of the build machine it works fine. But when run in the build script I get a "exited with code 3".
This is command that I am running:
C:\Program Files\Wavelink\Avalanche\PackageBuilder>.\jresdk\bin\java -classpath
"WLUtil.jar;WLPackageBuilder.jar" com.wavelink.buildpkg.AvalanchePackageBuilder
/build PackageName
This command only works when run from the above directory (I have tried running it from c:\ with the full path at it fails).
When I try to run it using ms build this is my statement:
<PropertyGroup>
<!--Working directory of the Package Builder Call-->
<PkgBldWorkingDir>"C:\Program Files\Wavelink\Avalanche\PackageBuilder"</PkgBldWorkingDir>
<!--Command line to run to make Package builder "go"-->
<PkgBldRun>.\jresdk\bin\java" -classpath "WLUtil.jar;WLPackageBuilder.jar" com.wavelink.buildpkg.AvalanchePackageBuilder</PkgBldRun>
</PropertyGroup>
<!--Run package builder command line to update the Ava File.-->
<Exec ContinueOnError="true" WorkingDirectory="$(PackageBuilderWorkingDir)"
Command="$(PkgBldRun) /build PackageName"/>
As I said above this "exits with code 3". This is the full output:
Task "Exec"
Command:
.\jresdk\bin\java -classpath "WLUtil.jar;WLPackageBuilder.jar" com.wavelink.buildpkg.AvalanchePackageBuilder /build PackageName
The system cannot find the path specified.
MSBUILD : warning MSB3073: The command ".\jresdk\bin\java -classpath "WLUtil.jar;WLPackageBuilder.jar" com.wavelink.buildpkg.AvalanchePackageBuilder /build PackageName" exited with code 3.
The previous error was converted to a warning because the task was called with ContinueOnError=true.
Build continuing because "ContinueOnError" on the task "Exec" is set to "true".
Done executing task "Exec" -- FAILED.
It says it can't find the file (who knows what file).
Any ideas on how to make this run a command line action in MS Build?
So... here is the answer.
First my code had a error in it. I defined my working directory as PkgBldWorkingDir but used it as PackageBuilderWorkingDir. That was my first error.
The second one was putting quotes in my working dir property (PkgBldWorkingDir). The " messes that up. Don't pass them in when setting up a working directory. It can handle spaces in a path with out the quotes.