Microsoft.WebApplication.targets was not found MSBuild [duplicate] - c#

Trying to build my project on the build server gives me the following error:
Microsoft (R) Build Engine Version 4.0.30319.1
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\TeamData\Microsoft.Data.Schema.SqlTasks.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
I solved this problem a few months ago, with installing Visual Studio 2010 on the Build Server. But now I'm setup a new server from scratch, and I want to know if there any better solution to solve this issue.

To answer the title of the question (but not the question about the output you're getting):
Copying the following folder from your dev machine to your build server fixes this if it's just web applications
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications
Remove x86 according to how your build breaks. If you have other project types you will probably need to copy the entire msbuild folder.

The solution would be to install redistributable packages on build server agent. It can be accomplished multiple ways, out of which 3 are described below. Pick one that suits you best.
Use installer with UI
this is the original answer
Right now, in 2017, you can install WebApplication redists with MSBuildTools. Just go to this page that will download MSBuild 2017 Tools and while installation click Web development build tools to get these targets installed as well:
This will lead to installing missing libraries in C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications by default
Use command line
disclaimer I haven't tested any of the following proposals
As #PaulHicks and #WaiHaLee suggested in comments, it can also be installed in headless mode (no ui) from CLI, that might actually be preferable way of solving the problem on remove server.
Solution A - using package manager (choco)
choco install visualstudio2017-workload-webbuildtools
Solution B - run installer in headless mode
Notice, this is the same installer that has been proposed to be used in original answer
vs_BuildTools.exe --add Microsoft.VisualStudio.Workload.WebBuildTools --passive

Building and publishing WAPs is not supported if VS is not installed. With that said, if you really do not want to install VS then you will need to copy all the files under %ProgramFiles32%\MSBuild\Microsoft\.
You will need to install the Web Deploy Tool as well. I think that is it.

UPD: as of VS2017, there is workload in Build Tools that eliminates this problem completely. See #SOReader answer.
If you'd prefer not to modify anything on build server, and you still want the project to build right out of source control, it might be a good idea to put the required binaries under source control. You'll need to modify the imports section in your project file to look like this:
<Import Project="$(SolutionDir)\BuildTargets\WebApplications\Microsoft.WebApplication.targets" />
<Import Condition="false" Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
The first line is the actual import from the new location that is relative to the solution directory. The second one is a turned-off version (Condition="false") of the original line that allows for Visual Studio to still consider your project to be a valid Web Application Project (that's the trick that VS 2010 SP1 does itself).
Don't forget to copy the C:\Program Files (x86)\Microsoft\VisualStudio\v10.0\WebApplications to BuildTargets folder under your source control.

You can also use the NuGet package MSBuild.Microsoft.VisualStudio.Web.targets, referencing them within your Visual Studio project(s), then change your references as Andriy K suggests.

Based on this post here you can simply download the Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package and the targets are installed.
This avoids the need to install Visual Studio on the build server.
I have just tried this out now, and can verify that it works:
Before:
error MSB4019: The imported project "C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets"
was not found. Confirm that the path in the declaration is
correct, and that the file exists on disk.
After the install:
[Builds correctly]
This is a far better solution than installing Visual Studio on a build server, obviously.

The latest Windows SDK, as mentioned above, in addition to the "Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package" for Microsoft.WebApplication.targets and "Microsoft Visual Studio Team System 2008 Database Edition GDR R2" for Microsoft.Data.Schema.SqlTasks.targets should alleviate the need to install Visual Studio 2010. However, installing VS 2010 maybe actually be less overall to download and less work in the end.

Add dependency through NuGet & set a Build Parameter
Goal: no changes / installs necessary to the build agents
I have taken a hybrid approach to the NuGet approach by Lloyd here, which was based off of the committing binary dependencies solution by Andrik.
The reason why is I want to be able to add new build agents without having to pre-configure them with items such as this.
On a machine with Visual Studio, Open the solution; ignore that the web project fails.
In the NuGet package manager, add MSBuild.Microsoft.VisualStudio.Web.targets, as Lloyd mentioned.
This will resolve the binaries to [solution]\packages\MSBuild.Microsoft.VisualStudio.Web.targets.nn.n.n.n\tools\VSToolsPath\
You can copy these to a references folder & commit,
Or just use them where they are at. I chose this, but I'm going to have to deal with the version number in the path later.
In Version 7, I did the following. This may not have been necessary, and based on the comments is definitely not needed now. Please see the comments below.
Next, in your TeamCity build configuration, add a build Paramenter for env.VSToolsPath and set it to the VSToolsPath folder; I used ..\packages\MSBuild.Microsoft.VisualStudio.Web.targets.11.0.2.1\tools\VSToolsPath

When building on the build/CI server, turn off the import of Microsoft.WebApplication.targets altogether by specifying /p:VSToolsPath=''. This will, essentially, make the condition of the following line false:
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
This is how it's done in TeamCity:

If you migrate Visual Studio 2012 to 2013, then open *.csproj project file with edior.
and check 'Project' tag's ToolsVersion element.
Change its value from 4.0 to 12.0
From
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" ...
To
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" ...
Or If you build with msbuild then just specify VisualStudioVersion property
msbuild /p:VisualStudioVersion=12.0
Solution Source

It seems the new version of msbuild does not ship with Microsoft.WebApplication.targets. To fix you need to update your csproj file as so:
1) Edit the web app csproj (right click). Find the section in the csproj towards the bottom concerning build tools. It should look like so.
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
2) You need to add one VSToolsPath line below the VisualStudioVersion tag so it looks like so
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<!--Add the below line to fix the project loading in VS 2017 -->
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<!--End -->
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
Reference link:
https://alastaircrabtree.com/cannot-open-vs-2015-web-project-in-vs-2017/

This is all you need. Only 103MB. Don't install everything

I have found this on MS connect:
Yes, you need to install Visual Studio
2010 on your build machine to build
database projects. Doing so does
not require an additional license of
Visual Studio.
So, this is the only option that I have for now.

Anyone coming here for Visual Studio 2017. I had the similar issue and couldn't compile the project after update to 15.6.1.
I had to install MSBulild tools but still the error was there.
I was able to fix the issue by copying the v14.0 folder from C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio to the same folder as v15.0 and that resolved all the errors.
So now my folder structure looks like below, where both folders contain the same content.

If you are using MSBuild, as in the case of a build server, what worked for me is:
Change the following:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
to:
<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
My Msbuild command is: *"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" solution.sln /p:Configuration=Debug /p:Platform="Any CPU"*
Hope this helps someone.

My solution is a mix of several answers here.
I checked the build server, and Windows7/NET4.0 SDK was already installed, so I did find the path:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets`
However, on this line:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
$(MSBuildExtensionsPath) expands to C:\Program Files\MSBuild which does not have the path.
Therefore what I did was to create a symlink, using this command:
mklink /J "C:\Program Files\MSBuild\Microsoft\VisualStudio" "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio"
This way the $(MSBuildExtensionsPath) expands to a valid path, and no changes are needed in the app itself, only in the build server (perhaps one could create the symlink every build, to make sure this step is not lost and is "documented").

I fixed this by adding
/p:VCTargetsPath="C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V120"
into
Build > Build a Visual Studio project or solution using MSBuild > Command Line Arguments

I tried a bunch of solutions, but in the end this answer worked for me: https://stackoverflow.com/a/19826448/431522
It basically entails calling MSBuild from the MSBuild directory, instead of the Visual Studio directory.
I also added the MSBuild directory to my path, to make the scripts easier to code.

I was having this issue building a SQL Server project on a CI/CD pipeline. In fact, I was having it locally as well, and I did not manage to solve it.
What worked for me was using an MSBuild SDK, capable of producing a SQL Server Data-Tier Application package (.dacpac) from a set of SQL scripts, which implies creating a new project. But I wanted to keep the SQL Server project, so that I could link it to the live database through SQL Server Object Explorer on Visual Studio. I took the following steps to have this up and running:
Kept my SQL Server project with the .sql database scripts.
Created a .NET Standard 2.0 class library project, making sure that the target framework was .NET Standard 2.0, as per the guidelines in the above link.
Set the contents of the .csproj as follows:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="MSBuild.Sdk.SqlProj/1.0.0">
<PropertyGroup>
<SqlServerVersion>Sql140</SqlServerVersion>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
I have chosen Sql140 as the SQL Server version because I am using SQL Server 2019. Check this answer to find out the mapping to the version you are using.
Ignore the SQL Server project on build, so that it stops breaking locally (it does build on Visual Studio, but it fails on VS Code).
Now we just have to make sure the .sql files are inside the SDK project when it is built. I achieved that with a simple powershell routine on the CI/CD pipeline that would copy the files from the SQL Server project to the SDK project:
Copy-Item -Path "Path.To.The.Database.Project\dbo\Tables\*"
-Destination (New-item -Name "dbo\Tables" -Type Directory -Path "Path.To.The.DatabaseSDK.Project\")
PS: The files have to be physically in the SDK project, either in the root or on some folder, so links to the .sdk files in the SQL Server project won't work. In theory, it should be possible to copy these files with a pre-build condition, but for some obscure reason, this was not working for me. I tried also to have the .sql files on the SDK project and link them to the SQL Server project, but that would easily break the link with the SQL Server Object Explorer, so I decided to drop this as well.

In case if you're trying to deploy a project using VSTS, then issue might be connected with checking "Hosted Windows Container" option instead of "Hosted VS2017"(or 18, etc.):

I fixed this by running the build in a docker container, specifically dotnet/framework/sdk. It includes the VS build tools.

Creating a new project and copying over the settings should probably provide the best guidance in what to do. This is what it looks like on mine
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />

In my case, It was just a Port-Block.

After installation of MSBuild tools from Microsoft, define the MSBuild path in the environment variable, so that it can be run from any path.
Edit the .csproj file in any notepad editor such as notepad++, and comment the
Check for the following elements,
-->
Make sure you use import only once, choose whichever works.
Make sure you have the following folder exists on the drive, "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0" or whichever version is referenced by MSBuild target at "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets"
From the command prompt, run the following command, to check
C:>msbuild "C:\\DotnetCi.sln" /p:Configuration=Release /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false
choose /p switch as appropriate, refer to enter link description here
enter image description here

Related

The command "esriRegasm.exe ..." exited with code -1. I can't build a project

I want to build the project to create a tool with ArcObjects in Visual Studio. I get this error:
The command "esriRegasm.exe "...Project1.dll" /p:Desktop /s" exited with code -1.
I use C#, Visual Studio 2015, ArcObjects 10.5, ArcMap 10.5.
I looked at past questions with the same error (External tool (esriRegasm.exe) fails during build. Where in my VS project is it executed?).
I tried to solve the problem like this:
tried to open the solution as an "adminimtrator" not just a user;
run the esriRegAsm.exe command from the command line. I tried in two ways. The first, as in the error in Visual Studio (picture 1) and the second, as per the instructions on the help.arcgis website. (picture 2);
tried to open the .csproj file, go to the end of the file, find the line esriRegAsm.exe, delete it and rebuild the project.
None of this worked. How to build a project?
The esriregasm-tool is used to register your own commands, tools or extension for using in ArcGIS. It is usually defined as msbuild-task at the end of your csproj-file as follows:
<Target Name="BeforeClean" Condition=" '$(NO_ESRI_REGASM)' == '' ">
<Exec WorkingDirectory="$(CommonProgramFiles)\ArcGIS\bin" Command="esriRegasm.exe "$(TargetPath)" /p:Desktop /u /s" Condition="Exists('$(TargetPath)')" />
</Target>
<Target Name="AfterBuild" Condition=" '$(NO_ESRI_REGASM)' == '' ">
<Exec WorkingDirectory="$(CommonProgramFiles)\ArcGIS\bin" Command="esriRegasm.exe "$(TargetPath)" /p:Desktop /s" />
</Target>
As I get this eror on nearly every rebuild of my solution, I developed a couple of strategies to handle it.
First you can just build the project again. As this won´t invoke the forementioned targets - only on "Clean" or "Rebuild", but not on "Build" - the registration is not executed. However your assembly is created. You can still register it after being compiled, either by rightclicking on the dll-file and selecting Register, or by calling the following within the commandline:
%CommonProgramFiles%\ArcGIS\bin\esriregasm /p:Desktop /u
%CommonProgramFiles%\ArcGIS\bin\esriregasm /p:Desktop
Be aware that I omitted the /s-flag in order to get more meaningul errors. You can also append the /e-switch for more verbose errors - which is not really much from my experience.
Now look into folder where the ECFG-files are located. This is usually %CommnonProgramFiles%\ArcGIS\Desktop<version>\Configuration\CATID. Make sure there is a file with the name of your assembly and the extension ecgf (it may also have some GUID at the beginning, e.g. {6d102248-13e2-40a0-8011-378543f63901}_MyAssembly.ecfg). This is just some zip-archieve, you can also unzip it and find an xml-file containing the GUIDs of your commands and tools. If registering the assembly didn´t work with the step mentioned before, you can just delete that ecfg-file and re-build (!!) your assembly. Then verify the file was created in that folder.
If that still does not work, just delete your compiled assembly alltogether with an eventually existing ecfg-file and re-build again.

How to add an existing widget to Nopcommerce?

I am really new to Nopcommerce. I have an existing plugin [A slider widget for homepage]. I was trying to add the Nop.Plugin.Widget.PromoSlider.csproj file in the Plugins directory from Visual Studio 17 but got the following error:
The imported project
"S(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" was
not found. Also, tried to find
"S(VSToolsPath)\WebApplications\Mlicrosoft.WebApplication.targets" in
the fallback search path(s) for $(VSToolsPath) - "C:\Program
Files(x86)\MSBuild\Microsoft\VisualStudio\v15.0" These search paths
are defined in "C:\Users***\AppData\Local\
Microsoft\VisualStudio\15.0_f96fcd52\devenv.exe.config". Confirm that
the path in the declaration is correct, and that the file
exists on disk in one of the search paths. C:\Users****\Deskctop\
Nop.Plugin.Widget.PromoSlider\Nop.Plugin.Widget.PromoSlider.csproj
Can anyone help me fix this error?
I guess you are trying to add a visual studio 2015 project in visual studio 2017. There is a ongoing investigation on this issue. But there is a workaround on this as well. Please check here for more details.
One work around is changing the following line (editing Nop.Plugin.Widget.PromoSlider.csproj)
<Import Project="$(VSToolsPath)\Web\Microsoft.Web.Publishing.targets" Condition="'$(VSToolsPath)' != ''" />
to
<Import Project="/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild/Microsoft/VisualStudio/v14.0/WebApplications/Microsoft.WebApplication.targets" />
Give it a try

TFSBuild 2013 unable to change msbuild version

I have a TFSBuild 2013 server that we are trying to now build UWP projects with, but we cannot seem to make it use the correct MSBuild version.
Symptoms:
When building the UWP projects, we get lots of errors like this:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\AppxPackage\Microsoft.AppXPackage.Targets (283): A numeric comparison was attempted on "10.0.11000.0" that evaluates to "10.0.11000.0" instead of a number, in condition "'$(TargetPlatformVersion)' >= '10.0.11000.0'".
Many reports abound for this error, all telling you to ensure that TFS Build is using the correct version of the MSBuild. And herein lies the issue. We cannot seem to make the build server use the correct version.
Here is what we have tried (build definitions are using TfvcTemplate.12.xaml template):
Installing 2015 build tools (update 3) on the build server
Installing VS2015 on the build server (Yuck)
Various combinations of MSBuild parameters in the build definition. (/tv:14.0 & /p:VisualStudioVersion=14.0)
Inclusion of Microsoft.Net.Compilers nuget package
Editing the TfvcTemplate.12.xaml template and setting "Run MSBuild" step to set "ToolsVersion" to "14.0". (Note, there is no "ToolsPath" setting in this version of the template, so I cant do that).
Setting ToolsVersion="14.0" in every .csproj file
No matter what we change, we cannot get the Build Agent to use the 14.0 version of MSBuild.
Strangely, nuget seems to find the correct version when doing the package restore. In the logs we see this when running the nuget.exe restore command: MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
But further down in the logs, where all the errors start we see this (note: wrong tools version):
C:\Program Files (x86)\MSBuild\12.0\bin\MSBuild.exe /nologo /noconsolelogger "C:\Builds..." [SNIP]
Any help or suggestions gratefully received - I'm at my wits end :)
I finally gave up trying to make this behave with configuration, but managed to get this working on the build machine by hacking the registry.
I changed the following registry keys:
HKLM\SOFTWARE\Wow6432Node\Microsoft\MSBuild\12.0\MSBuildOverrideTasksPath
HKLM\SOFTWARE\Wow6432Node\Microsoft\MSBuild\ToolsVersions\12.0\MSBuildToolsPath
In both cases, I changed the value
from:
C:\Program Files (x86)\MSBuild\12.0\bin\
to:
C:\Program Files (x86)\MSBuild\14.0\bin\
Disclaimer: I don't know what other affects this will have, but its got our builds using the correct MSBuild version, and is limited in scope to the build server.
Editing the TfvcTemplate.12.xaml template and setting "Run MSBuild" step to set "ToolsVersion" to "14.0".
This will work if you also add the following piece in the MSBuild 12.0 config file (as described here)
<msbuildToolsets>
<toolset toolsVersion="14.0">
<property name="MSBuildToolsPath" value="C:\Program Files (x86)\MSBuild\14.0\Bin\" />
</toolset>
</msbuildToolsets>
Please note there is also amd64 folder in the MSbuild\bin directory which has its own config file

How to programmatically update project references in a Visual Studio project

I have a file structure like the following:
- binaries
- binary1.dll
- dev
- <developer-name>
- a.csproj
-trunk
- a.csproj
Developers who need to work on a.csproj will create a branch in dev and they will work from there. Our projects need to have a reference to binary1.dll in the binaries directory.
If the reference is a relative path (the Visual Studio default) then the path will not work both for the project in trunk and the project in the developer's branch.
To work around this problem I thought of creating an environment variable and using that in the project file instead:
<Reference Include="binary1">
<HintPath>$(MY_ENV_VAR)\binary1.dll</HintPath>
</Reference>
This works perfectly, but I wanted to help developers add references more easily, so I wrote a program that will convert relative paths that point to binary1.dll (for example, from the dev branch a.csproj it would change the path ../../binaries/binary1.dll to $(MY_ENV_VAR)\binary1.dll) but I have not figured out how to get that to work.
If I use a pre-build event, the project is already loaded into memory and the event return an error because it cannot write the project file.
Then I realized that I could override MSBuild targets, and attempted with the targets: BeforeCompiler, AfterCompiler, BeforeBuild, AfterBuild and in all of them the project is already locked.
Then I ran into this answer and I modified my code to call the executable in the GenerateApplicationManifest target, but that one doesn't seem to call the executable at all.
Some other ideas that I have been playing with are creating a new project that does the updating of the second project and have a link between them, but that would duplicate the number of projects.
I could also just change the depth of trunk, but that only hides the problem and doesn't really solve it. When developers create a branch inside their dev branch to work on different features or bugs then I have the same problem all over again.
There might also be another feature which fixes this in a more elegant way, but I haven't been able to find anything.
So my question: How do I get MS Build or pre-build events to modify a CS project?
I found a way to do this. The issue was that the Visual Studio process itself was locking the project, but Visual Studio could overwrite the file. I ended up modifying a.csproj to include:
<Target Name="BeforeBuild">
<Exec Command="UpdateReferences.exe" /> <!-- This creates the $(ProjectPath).new file -->
<Move SourceFiles="$(ProjectPath).new" DestinationFiles="$(ProjectPath)" />
</Target>

Using msbuild to execute a File System Publish Profile

I have a c# .Net 4.0 project created with VS2010 and now being accessed with VS2012.
I'm trying to publish only the needed files from this website to a destination location (C:\builds\MyProject[Files])
My file structure:
./ProjectRoot/MyProject.csproj
./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml
I'm running the following via MSBuild:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ./ProjectRoot/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml
Here's the xml in FileSystemDebug.pubxml
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>C:\builds\MyProject\</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
</Project>
The resulting behavior is:
a zip file is created here:./ProjectRoot/obj/Debug/Package/MyProject.zip
Nothing is deployed to <publishUrl>C:\builds\MyProject\</publishUrl> WTF
the zip file that is created is a pigs breakfast and full of files that aren't needed for the application.
When I run this publish profile through visual studio a folder is created at *C:\builds\MyProject* and contains the exact artifacts that I want.
How do I get this simple result from msbuild?
FYI: I had the same issue with Visual Studio 2015. After many of hours trying, I can now do msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile=myprofile.
I had to edit my .csproj file to get it working. It contained a line like this:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets"
Condition="false" />
I changed this line as follows:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets" />
(I changed 10.0 to 14.0, not sure whether this was necessary. But I definitely had to remove the condition part.)
Found the answer here:
http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild
Visual Studio 2010 has great new Web Application Project publishing
features that allow you to easy publish your web app project with a
click of a button. Behind the scenes the Web.config transformation and
package building is done by a massive MSBuild script that’s imported
into your project file (found at: C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets).
Unfortunately, the script is hugely complicated, messy and
undocumented (other then some oft-badly spelled and mostly useless
comments in the file). A big flowchart of that file and some
documentation about how to hook into it would be nice, but seems to be
sadly lacking (or at least I can’t find it).
Unfortunately, this means performing publishing via the command line
is much more opaque than it needs to be. I was surprised by the lack
of documentation in this area, because these days many shops use a
continuous integration server and some even do automated deployment
(which the VS2010 publishing features could help a lot with), so I
would have thought that enabling this (easily!) would be have been a
fairly main requirement for the feature.
Anyway, after digging through the Microsoft.Web.Publishing.targets
file for hours and banging my head against the trial and error wall,
I’ve managed to figure out how Visual Studio seems to perform its
magic one click “Publish to File System” and “Build Deployment
Package” features. I’ll be getting into a bit of MSBuild scripting, so
if you’re not familiar with MSBuild I suggest you check out this crash
course MSDN page.
Publish to File System
The VS2010 Publish To File System Dialog Publish to File System took
me a while to nut out because I expected some sensible use of MSBuild
to be occurring. Instead, VS2010 does something quite weird: it calls
on MSBuild to perform a sort of half-deploy that prepares the web
app’s files in your project’s obj folder, then it seems to do a manual
copy of those files (ie. outside of MSBuild) into your target publish
folder. This is really whack behaviour because MSBuild is designed to
copy files around (and other build-related things), so it’d make sense
if the whole process was just one MSBuild target that VS2010 called
on, not a target then a manual copy.
This means that doing this via MSBuild on the command-line isn’t as
simple as invoking your project file with a particular target and
setting some properties. You’ll need to do what VS2010 ought to have
done: create a target yourself that performs the half-deploy then
copies the results to the target folder. To edit your project file,
right click on the project in VS2010 and click Unload Project, then
right click again and click Edit. Scroll down until you find the
Import element that imports the web application targets
(Microsoft.WebApplication.targets; this file itself imports the
Microsoft.Web.Publishing.targets file mentioned earlier). Underneath
this line we’ll add our new target, called PublishToFileSystem:
<Target Name="PublishToFileSystem"
DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
<Error Condition="'$(PublishDestination)'==''"
Text="The PublishDestination property must be set to the intended publishing destination." />
<MakeDir Condition="!Exists($(PublishDestination))"
Directories="$(PublishDestination)" />
<ItemGroup>
<PublishFiles Include="$(_PackageTempDir)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(PublishFiles)"
DestinationFiles="#(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="True" />
</Target>
This target depends on the
PipelinePreDeployCopyAllFilesToOneFolder target, which is what VS2010
calls before it does its manual copy. Some digging around in
Microsoft.Web.Publishing.targets shows that calling this target causes
the project files to be placed into the directory specified by the
property _PackageTempDir.
The first task we call in our target is the Error task, upon which
we’ve placed a condition that ensures that the task only happens if
the PublishDestination property hasn’t been set. This will catch you
and error out the build in case you’ve forgotten to specify the
PublishDestination property. We then call the MakeDir task to create
that PublishDestination directory if it doesn’t already exist.
We then define an Item called PublishFiles that represents all the
files found under the _PackageTempDir folder. The Copy task is then
called which copies all those files to the Publish Destination folder.
The DestinationFiles attribute on the Copy element is a bit complex;
it performs a transform of the items and converts their paths to new
paths rooted at the PublishDestination folder (check out Well-Known
Item Metadata to see what those %()s mean).
To call this target from the command-line we can now simply perform
this command (obviously changing the project file name and properties
to suit you):
msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem
Still had trouble after trying all of the answers above (I use Visual Studio 2013). Nothing was copied to the publish folder.
The catch was that if I run MSBuild with an individual project instead of a solution, I have to put an additional parameter that specifies Visual Studio version:
/p:VisualStudioVersion=12.0
12.0 is for VS2013, replace with the version you use. Once I added this parameter, it just worked.
The complete command line looks like this:
MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0
I've found it here:
http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/command-line-deployment
They state:
If you specify an individual project instead of a solution, you have to add a parameter that specifies the Visual Studio version.
It looks to me like your publish profile is not being used, and doing some default packaging. The Microsoft Web Publish targets do all what you are doing above, it selects the correct targets based on the config.
I got mine to work no problem from TeamCity MSBuild step, but I did specify an explicit path to the profile, you just have to call it by name with no .pubxml (e.g. FileSystemDebug). It will be found so long as in the standard folder, which yours is.
Example:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ./ProjectRoot/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=FileSystemDebug
Note this was done using the Visual Studio 2012 versions of the Microsoft Web Publish targets, normally located at "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web". Check out the deploy folder for the specific deployment types targets that are used
Actually I merged all your answers to my own solution how to solve the above problem:
I create the pubxml file according my needs
Then I copy all the parameters from pubxml file to my own list of parameters "/p:foo=bar" for msbuild.exe
I throw away the pubxml file
The result is like that:
msbuild /t:restore /t:build /p:WebPublishMethod=FileSystem /p:publishUrl=C:\builds\MyProject\ /p:DeleteExistingFiles=True /p:LastUsedPlatform="Any CPU" /p:Configuration=Release
FYI: Same problem with running on a build server (Jenkins with msbuild 15 installed, driven from VS 2017 on a .NET Core 2.1 web project).
In my case it was the use of the "publish" target with msbuild that ignored the profile.
So my msbuild command started with:
msbuild /t:restore;build;publish
This correctly triggerred the publish process, but no combination or variation of "/p:PublishProfile=FolderProfile" ever worked to select the profile I wanted to use ("FolderProfile").
When I stopped using the publish target:
msbuild /t:restore;build /p:DeployOnBuild=true /p:PublishProfile=FolderProfile
I (foolishly) thought that it would make no difference, but as soon as I used the DeployOnBuild switch it correctly picked up the profile.
First check the Visual studio version of the developer PC which can publish the solution(project).
as shown is for VS 2013
/p:VisualStudioVersion=12.0
add the above command line to specify what kind of a visual studio version should build the project. As previous answers, this might happen when we are trying to publish only one project, not the whole solution.
So the complete code would be something like this
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" "C:\Program Files (x86)\Jenkins\workspace\Jenkinssecondsample\MVCSampleJenkins\MVCSampleJenkins.csproj" /T:Build;Package /p:Configuration=DEBUG /p:OutputPath="obj\DEBUG" /p:DeployIisAppPath="Default Web Site/jenkinsdemoapp" /p:VisualStudioVersion=12.0
Run from the project folder
msbuild /p:DeployOnBuild=true /p:PublishProfile="release-file.pubxml" /p:AspnetMergePath="C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" /p:Configuration=Release
This takes care of web.config Transform and AspnetMergePath

Categories