How to pass variable in a project file to the "MSBuild" task - msbuild

We are using a project file, which then calls MSBuild task. For example,
<Target Name="Clean">
<MSBuild Targets="Clean" Projects="#(Solution)"/>
</Target>
In the project file I now define a variable which I want to pass to MSBuild task.

I found it out by myself!
This works:
<Target Name="Clean">
<MSBuild Targets="Clean" Projects="#(Solution)" Properties="Key=Value"/>
</Target>

Related

Deleting parent folder msbuild

Am passing the the below path as parameter to msbuild project.
"D:\Tools\TestTools\Folder1\Folder2\Folder3"
How to I delete the "Folder1" by traversing this parameter using msbuild?
Thanks...
You could just split the path twice:
<Target Name="DeleteSubDir" DependsOnTargets="">
<PropertyGroup>
<Dir>D:\Tools\TestTools\Folder1\Folder2\Folder3</Dir>
<DirToDelete>$([System.IO.Path]::GetDirectoryName('$(Dir)'))</DirToDelete>
<DirToDelete>$([System.IO.Path]::GetDirectoryName('$(DirToDelete)'))</DirToDelete>
</PropertyGroup>
<RemoveDir Directories="$(DirToDelete)" />
</Target>
Just explicitly go two directories above:
<Target Name="DeleteSubDir" DependsOnTargets="">
<PropertyGroup>
<Dir>D:\Tools\TestTools\Folder1\Folder2\Folder3</Dir>
<DirToDelete>$([System.IO.Path]::GetFullPath('$(Dir)\..\..'))</DirToDelete>
</PropertyGroup>
<RemoveDir Directories="$(DirToDelete)" />
</Target>

Msbuild compile website without placing the site in IIS

I am trying to create a msbuild script that will compile and place a test app into a folder on my desktop. I do not want this app published to IIS. I have followed several blgos and looked through hashimi's book but I still cannot figure this out. Below is my script. Thank you very much!
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Clean">
<ItemGroup>
<BinFiles Include="bin\*.*" />
</ItemGroup>
<Delete Files="#(BinFiles)" />
</Target>
<Target Name="Compile" DependsOnTargets="Clean">
<MSBuild Projects="test.vbproj"/>
</Target>
<Target Name="Publish" DependsOnTargets="Compile">
<RemoveDir Directories="$(OutputFolder)"
ContinueOnError="true"/>
<MSBuild Projects="test.vbproj"
targets="ResolveReferences;_CopyWebApplication"
Properties="WebProjectOutputdir=$(OutputFolder; OutDir=$WebProjectOutputDir)\"/>
</Target>
</Target>
</Project>
Your script is a bit awkward (you redefined the clean target to do the same as the the basic clean target).
I'm pretty sure your problem comes from the CopyWebApplication which does lots of stuff according to the properties set in your project file and pass by command line.
Can you try the following script :
<Project DefaultTargets="Compile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Compile">
<MSBuild
Projects="test.vbproj"
Targets="Clean;Build"
Properties="OutputPath=C:\tmp"/>
</Target>
</Project>
if your test project is a website then the build target should create it on the folder specified in the OutputPath/OutDir property

Copy the content of the bin folder into a specific folder

So far I have this,but it's not working.
<Target Name="AfterBuild">
<Copy SourceFiles="bin\" DestinationFolder="C:\temp\appServer\"></Copy>
</Target>
Try this :
<ItemGroup>
<BinFiles Include="bin\**\*.*"/>
</ItemGroup>
<Target Name="AfterBuild">
<Copy SourceFiles="#(BinFiles)"
DestinationFolder="C:\temp\appServer\"/>
</Target>
Looks like the MSBuild Copy task doesn't take a directory for SourceFiles, but instead a list of files to copy.
Check out the MSDN article here for a simple example:
MSDN Link
Try using a file wildcard.
<Target Name="AfterBuild">
<Copy SourceFiles="bin\*.*" DestinationFolder="C:\temp\appServer\"></Copy>
</Target>

How can I change AssemblyProduct, AssemblyTitle using MSBuild?

I have an MSBuild script which compiles my existing solution but I'd like to change some properties of one of the projects within the solution at compile-time, including but not limited to AssemblyProduct and AssemblyTitle.
Here's a snippet of my build script:
<Target Name="Compile" >
<MSBuild Projects="..\MySolution.sln"
Properties="Configuration=MyReleaseConfig;Platform=x86" />
</Target>
I've got one main executable and several DLLs that are compiled. I am aware of the MSBuild Extension Pack and I suspect it might help me to get to where I need to be, although I'm not sure how to proceed.
Can I selectively change AssemblyInfo properties at build time?
You're on the right track with the MSBuild Extension Pack.
I find the easiest way to conditionally generate the assembly details at build time is to add an "AssemblyVersion" target directly to my .csproj file(s) that require an updated AssemblyInfo file. You can add the target directly to each csproj file that requires an updated AssemblyInfo file, or as I prefer to do it, create a custom targets file with the AssemblyVersion target and have each csproj file include your custom targets file.
Either way you likely want to use the MSBuild Extension Pack or the MSBuild Community Tasks to use their respective AssemblyInfo task.
Here's some code from our build scripts:
<!-- Import the AssemblyInfo task -->
<Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets"/>
<!-- Overriding the Microsoft.CSharp.targets target dependency chain -->
<!-- Call our custom AssemblyVersion target before build, even from VS -->
<PropertyGroup>
<BuildDependsOn>
AssemblyVersion;
$(BuildDependsOn)
</BuildDependsOn>
</PropertyGroup>
<ItemGroup>
<AssemblyVersionFiles Include="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs"/>
</ItemGroup>
<Target Name="AssemblyVersion"
Inputs="#(AssemblyVersionFiles)"
Outputs="UpdatedAssemblyVersionFiles">
<Attrib Files="%(AssemblyVersionFiles.FullPath)"
Normal="true"/>
<AssemblyInfo
CodeLanguage="CS"
OutputFile="%(AssemblyVersionFiles.FullPath)"
AssemblyCompany="$(CompanyName)"
AssemblyCopyright="Copyright $(CompanyName), All rights reserved."
AssemblyVersion="$(Version)"
AssemblyFileVersion="$(Version)">
<Output TaskParameter="OutputFile"
ItemName="UpdatedAssemblyVersionFiles"/>
</AssemblyInfo>
</Target>
Sneal's answer was very helpful, but I'd like to show what I actually ended up doing. Instead of editing csproj files (there are several) I instead added tasks to my build script. Here's a snippet:
<PropertyGroup>
<ProductName>MyApp</ProductName>
<CompanyName>MyCompany</CompanyName>
<Major>1</Major>
<Minor>0</Minor>
<Build>0</Build>
<Revision>0</Revision>
</PropertyGroup>
<ItemGroup>
<AssemblyVersionFiles Include="..\MyMainProject\Properties\AssemblyInfo.cs"/>
</ItemGroup>
<Target Name="AssemblyVersionMAIN" Inputs="#(AssemblyVersionFiles)" Outputs="UpdatedAssemblyVersionFiles">
<Attrib Files="%(AssemblyVersionFiles.FullPath)" Normal="true"/>
<AssemblyInfo
CodeLanguage="CS"
OutputFile="%(AssemblyVersionFiles.FullPath)"
AssemblyProduct="$(ProductName)"
AssemblyTitle="$(ProductName)"
AssemblyCompany="$(CompanyName)"
AssemblyCopyright="© $(CompanyName) 2010"
AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)"
AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)"
AssemblyInformationalVersion="$(Major).$(Minor).$(Build).$(Revision)">
<Output TaskParameter="OutputFile" ItemName="UpdatedAssemblyVersionFiles"/>
</AssemblyInfo>
</Target>
<Target Name="Compile" DependsOnTargets="AssemblyVersionMAIN">
<MSBuild Projects="..\MySolution.sln"
Properties="Configuration=Release;Platform=x86;Optimize=true" />
</Target>
Then, I can override my variables from the command line, or a batch script, like so:
set MAJ=1
set MIN=2
set BLD=3
set REV=4
msbuild buildScript.xml /t:Compile /p:Major=%MAJ% /p:Minor=%MIN% /p:Build=%BLD% /p:Revision=%REV%
<Target Name="SetVersion">
<ItemGroup>
<AssemblyInfoFiles Include="$(TargetDir)\**\AssemblyInfo.cs"/>
</ItemGroup>
<Message Text="change the Version number for:"/>
<Message Text="%(AssemblyInfoFiles.FullPath)"/>
<MSbuild.ExtensionPack.Framework.AssemblyInfo
AssemblyInfoFiles="#(AssemblyInfoFiles)"
AssemblyTitle="newTitle"
AssemblyMajorVersion="2"
AssemblyMinorVersion="0"/>
</Target>

MSBuild Copy task not copying files the first time round

I created a build.proj file which consists of a task to copy files that will be generated after the build is complete. The problem is that these files are not copied the first time round and I have to run msbuild again on the build.proj so that the files can be copied. Please can anyone tell me whats wrong with the following build.proj file:
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<SourcePath Condition="'$(SourcePath)' == ''">$(MSBuildProjectDirectory)</SourcePath>
<BuildDir>$(SourcePath)\build</BuildDir>
</PropertyGroup>
<ItemGroup>
<Projects
Include="$(SourcePath)\src\myApp\application.csproj">
</Projects>
</ItemGroup>
<Target Name="Build">
<Message text = "Building project" />
<MSBuild
Projects="#(Projects)"
Properties="Configuration=$(Configuration)" />
</Target>
<ItemGroup>
<OutputFiles Include ="$(MSBuildProjectDirectory)\**\**\bin\Debug\*.*"/>
</ItemGroup>
<Target Name="CopyToBuildFolder">
<Message text = "Copying build items" />
<Copy SourceFiles="#(OutputFiles)" DestinationFolder="$(BuildDir)"/>
</Target>
<Target Name="All"
DependsOnTargets="Build; CopyToBuildFolder"/>
</Project>
The itemgroups are evaluated when the script is parsed. At that time your files aren't there yet. To be able to find the files you'll have to fill the itemgroup from within a target.
<!-- SQL Scripts which are needed for deployment -->
<Target Name="BeforeCopySqlScripts">
<CreateItem Include="$(SolutionRoot)\04\**\Databases\**\*.sql">
<Output ItemName="CopySqlScript" TaskParameter="Include"/>
</CreateItem>
</Target>
This example creates the ItemGroup named "CopySqlScript" using the expression in the Include attribute.
Edit:
Now I can read your script: add the CreateItem tag within your CopyToBuildFolder target