Calling TransformWebConfig on a solution file - visual-studio-2010

I have a solution with multiple projects in it one of these projects is a web application and I would like to be able to transform the web.config using web.release.config when building the solution using MSBuild.
When I call
MSBuild "WebProject.csproj" /t:TransformWebConfig
/p:Configuration=Release
on the web project I get the transformed web.config output to ...\obj\Release\TransformWebConfig\transformed\ Web.config
but when I try to call
MSBuild "Solution.sln" /t:TransformWebConfig
/p:Configuration=Release
I get an error that "TransformWebConfig does not exist in the project". Is there a you to get this to work so it will output a transformed web.config if possible and ignore the TransformWebConfig part of the command otherwise?

The easiest way to do this seems to be to change the web projects .csproj file to
<Project ToolsVersion="4.0" DefaultTargets="BuildWithConfig" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
And then add a new target
<Target Name="BuildWithConfig">
<CallTarget Targets="Build"/>
<CallTarget Targets="TransformWebConfig"/>
</Target>
And then run
MSBuild "Solution.sln" /p:Configuration=Release
And the file will be output to ...\WebProject\obj\Release\TransformWebConfig\transformed

Related

How to add a project or target to msbuild solution that builds other projects in the same solution?

Wondering if there is an easy way to do what I want with Visual Studio solution.
I have a solution that has 10+ VC++ projects. These projects don't have any dependencies on each other. I want to create msbuild target on the solution that goes and builds all the sub projects.
Something like:
msbuild mysolution.sln /t:RebuildAll /p:Configuration=Debug
How do I add "RebuildAll" target to my solution that iterates all projects in the solution and invokes "Rebuild" target on them?
Thanks
According to your description I make some test, you can refer to the following steps:
Create a file named test.proj
Use this code in the file, remember to change your own solution path in the code:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectFile Include="Your solution path/**/*.vcxproj">
<Properties>Configuration=Release</Properties>
</ProjectFile>
</ItemGroup>
<Target Name="BuildAll">
<MSBuild Projects="#(ProjectFile)" BuildInParallel="true" />
</Target>
</Project>
Then use this msbuild command line to build your projects msbuild test.proj -t:BuildAll -v:normal -m:30.

Is it possible to run a post build event when the whole compilation finishes in Visual Studio 2013?

I have a solution with multiple projects and we use FxCop. We want to run it once the compilation requested finishes (it may be one project, a folder with several folders or the whole solution).
Is there a way of doing this? We currently do it per project but this has some drawbacks.
Yes, there is a way to do it by putting a file next to your solution file with a specific naming pattern: after.{Your solution name here}.sln.targets
<!--?xml version="1.0" encoding="utf-8"?-->
<project toolsversion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<target name="AtTheStart" beforetargets="Build">
<message text="GenerateCode target running" importance="high">
</message>
</target>
<target name="AtTheEnd" aftertargets="Build">
<message text="GenerateCode target running" importance="high">
</message>
</target>
</project>
But if you want to run FxCop effectively and have visualstudio installed, you can actually activate it during the build by including /p:RunCodeAnalysis=true or /p:RunCodeAnalysis=always on the call to MsBuild. This will run the configured ruleset file during the build. /p:CodeAnalysisRuleSet=PathTo.ruleset will let you specify a specific ruleset file.
The commandline will always overwrite the project's own configuration. And it will run in the most optimal way.
I would put the FxCop project set (with all the dll's in all your projects) and call it after all the projects are built in VS.

How do I use an MSBuild file from Visual Studio 2012?

I have a simple MSBuild file that I'm learning with.
Here it is:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Clean" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{D5A16164-962E-4A6D-9382-240F31AB6C50}</ProjectGuid>
</PropertyGroup>
<Target Name="Clean">
<ItemGroup>
<BinFiles Include="bin\*.*" />
<fff Include="f\*.*" />
</ItemGroup>
<Delete Files="#(BinFiles)" />
<Delete Files="#(fff)" />
</Target>
</Project>
Now I want to include this in a Visual Studio solution and be able to run the "clean" target from Visual Studio 2012. I tried naming it testproject.msbuildproj like the internet seems to suggest "works", but it doesn't work. When I run the clean command I just get "unexpected error".
If I rename the project to testproject.csproj, it does some unintuitive things like creating compilation directories, but it does actually run my clean command properly. However, this is undesireable because it creates obj and bin/x86/debug type directories. It also looks goofy in Visual Studio because it still gives the References drop down.
How can I use just a plain vanilla MSBuild project from Visual Studio without random errors or false assumptions?
Note I only am having a problem with this from Visual Studio. Using msbuild from the command line it works perfectly
Visual Studio creates bin / obj folders when it opens csproj file. When you click Build / Rebuild / Clean it just uses appropriate targets from the project file.
You cannot stop VS from creating these folders, but you can ask it to create them in say temp folder by setting appropriate properties - refer this MSDN article for details.
So the steps are to rename your project to csproj, and add the following lines into project:
<PropertyGroup>
<OutputPath>$(Temp)\bin</OutputPath>
<IntermediateOutputPath>$(Temp)\obj</IntermediateOutputPath>
</PropertyGroup>
I usually use a bit different approach to work with MSBUILD files from VS:
I use regular csproj file with removed Import ... CSharp.targets part as pure container for my Build projects.
I add actual build files with targets and logic, and all properties, necessary artifacts like XSLT etc using "Include into project", so I can manage hierarchy and change any file from within VS.Net.
I redefine Build / Rebuild targets in csproj file for whatever I need, for example Build may contain minimum output, and while rebuild diagnostic one.
Like this:
<Target Name="Build">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe Builds\build.proj /t:Build /v:m" />
</Target>
<Target Name="Rebuild">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe Builds\build.proj /t:Build /v:d" />
</Target>

Using MSBuild.exe to "Publish" a ASP.NET MVC 4 project with the cmd line

I'm looking for a command to run against the MSBuild.exe that just takes a MVC 4 project and publishes it to a given directory.
For example,
MSBuild <solution>/<project>.csproj -publish -output=c:/folder
This is obviously incorrect syntax. I'm trying to simplify my question.
This question talks of a build XML, but I'm not trying to do anything with that much detail.
I'm simply trying to do a deploy.
Further down in that question, someone speaks of "MSDeploy". I can look into that, but is it the only option? I do not have the ability to install web deploy on the server. In which case, all I really need to do is "Publish" and send the contents of the published project to a given directory on the server/file-system.
Does anyone have a one liner I can use?
Do I have to use MSDeploy?
Does MSDeploy require web deploy to be installed on the server?
Doesn't setting up web deploy on the server require setting up some ports, permissions, and installing some IIS add-ons?
I'd love to just execute something simple.
In VS 2012 (as well as the publish updates available in the Azure SDK for VS 2010) we have simplified command line publishing for web projects. We have done that by using Publish Profiles.
In VS for a web project you can create a publish profile using the publish dialog. When you create that profile it is automatically stored in your project under Properties\PublishProfiles. You can use the created profile to publish from the command line with a command line the following.
msbuild mysln.sln /p:DeployOnBuild=true /p:PublishProfile=<profile-name>
If you want to store the publish profile (.pubxml file) in some other location you can pass in the path to the PublishProfile.
Publish profiles are MSBuild files. If you need to customize the publish process you can do so directly inside of the .pubxml file.
If your end goal is to pass in properties from the command line. I would recommend the following. Create a sample publish profile in VS. Inspect that publish profile to determine what MSBuild properties you need to pass in on the command line. FYI not all publish method support command line publishing (i.e. FTP/FPSE).
FYI if you are building the .csproj/.vbproj instead of the .sln and you are using VS 2012 you should also pass in /p:VisualStudioVersion=11.0. For more details as to why see http://sedodream.com/2012/08/19/VisualStudioProjectCompatabilityAndVisualStudioVersion.aspx.
Create a build.xml file thats look like below
Start Visual Studio command prompt
Run msbuild build.xml
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
<PropertyGroup>
<Build>$(MSBuildProjectDirectory)\Build</Build>
<ProjectFile>MyProject.csproj</ProjectFile>
<ProjectName>MyProjectNameInVisualStudio</ProjectName>
<CopyTo>$(MSBuildProjectDirectory)\CopyTo</CopyTo>
</PropertyGroup>
<Target Name="Build">
<RemoveDir Directories="$(Build)"/>
<MSBuild Projects="$(ProjectFile)" Properties="Configuration=Release;OutputPath=$(Build);OutDir=$(Build)/"></MSBuild>
<Exec Command="robocopy.exe $(Build)\_PublishedWebsites\$(ProjectName) $(CopyTo) /e /is
if %errorlevel% leq 4 exit 0 else exit %errorlevel%"/>
</Target>
</Project>
The command below works perfect:
msbuild Myproject.sln /t:Rebuild /p:outdir="c:\outproject\\" /p:Configuration=Release /p:Platform="Any CPU"
I found Sayed's answer was deploying the default configuration i.e. Debug. The configuration selected in the Publishing Profile seems to get ignored by MSBuild. Accordingly I changed the command to specify the correct configuration for the deployment...
msbuild mysln.sln /p:Configuration=[config-name] /p:DeployOnBuild=true /p:PublishProfile=[profile-name]
where config-name = Release or some other build configuration you've created
With web projects you need to build, as per above, but then you also need to package/copy. We use a file copy, rather than the "publish"...
Also; we use DEBUG/RELEASE to build the website; but then actual environments, ie "QA" or "PROD" to handle the web.config transforms.
So we build it initially with RELEASE, and then package it with QA - in the example below.
<PropertyGroup>
<SolutionName>XXX.Website</SolutionName>
<ProjectName>XXX.Website</ProjectName>
<IisFolderName>XXX</IisFolderName>
<SolutionConfiguration>QA</SolutionConfiguration> <!--Configuration will be set based on user selection-->
<SolutionDir>$(MSBuildThisFileDirectory)..</SolutionDir>
<OutputLocation>$(SolutionDir)\bin\</OutputLocation>
<WebServer>mywebserver.com</WebServer>
</PropertyGroup>
<Target Name="BuildPackage">
<MSBuild Projects="$(SolutionDir)\$(SolutionName).sln" ContinueOnError="false" Targets="Clean;Rebuild" Properties="Configuration=Release" />
<MSBuild Projects="$(SolutionDir)\$(ProjectName)\$(ProjectName).csproj" ContinueOnError="false" Targets="Package" Properties="Configuration=$(SolutionConfiguration);AutoParameterizationWebConfigConnectionStrings=False" />
</Target>
<Target Name="CopyOutput">
<ItemGroup>
<PackagedFiles Include="$(SolutionDir)\$(ProjectName)\obj\$(SolutionConfiguration)\Package\PackageTmp\**\*.*"/>
</ItemGroup>
<Copy SourceFiles="#(PackagedFiles)" DestinationFiles="#(PackagedFiles->'\\$(WebServer)\$(IisFolderName)\$(SolutionConfiguration)\%(RecursiveDir)%(Filename)%(Extension)')"/>
</Target>
So;
Setup your properties
Call the BuildPackage target
Call the CopyOutput target
And voila!

Run other than the DefaultTarget for a project configuration under Visual Studio 2010

I've a MSBuild target in my csproj to copy files and folders of my web application to a target path after build.
<Target Name="PublishToFileSystem" DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
...
If I call MSBuild via command line with the target "PublishToFileSystem" everything works fine.
But now I want to "use" this target also for a special configuration in Visual Studio (like Release, Debug, ...).
How can I assign a configuration to another target than the DefaultTarget "Build" set in the project with DefaultTargets:
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Thanks, Konrad
Try to use AfterBuild target instead of PublishToFileSystem:
<Target Name="AfterBuild" DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
or check Overriding Predefined Targets on MSDN
If you want to do this for a specific solution configuration and you're suffering from ciruclar dependencies as I was, the easiest thing I could come up with is writing your own Target to use as default target. That target starts other targets based on a condition on the configuration.
<Target Name="CustomBuild">
<CallTarget Targets="SignAndroidPackage" Condition="'$(Configuration)' == 'UITest'"/>
<CallTarget Targets="Build" Condition="'$(Configuration)' != 'UITest'"/>
</Target>
And then simply change the Default target at the top of the project definition to that CustomBuild target.
<Project DefaultTargets="CustomBuild" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Here's an approach that might suit your need: run a custom msbuild target from VisualStudio
(this is trick #78 in the book MSBuild Trickery)

Resources