MSBuild task configuration property - msbuild

I have three Visual Studio solutions. The first is configured to build as Release, and the other two are set to build as Debug.
When running a simple MSBuild script explicitly stating the configuration to build (Debug), the first project is still built as Release.
Sample script:
<Target Name="Build">
<ItemGroup>
<ProjectToBuild Include="$(SolutionsPath)\Solution1.sln"/>
<ProjectToBuild Include="$(SolutionsPath)\Core\Solution2.sln"/>
<ProjectToBuild Include="$(SolutionsPath)\UI\Solution3.sln"/>
</ItemGroup>
<MSBuild Projects="#(ProjectToBuild)"
Targets="Rebuild"
Properties="Configuration=Debug;Platform=Any CPU"/>
</Target>
I have tried variations of the above such as the following, but I always end up with the same result.
<Target Name="Build">
<ItemGroup>
<ProjectToBuild Include="$(SolutionsPath)\Solution1.sln">
<Properties>Configuration=Debug</Properties>
</ProjectToBuild>
<ProjectToBuild Include="$(SolutionsPath)\Core\Solution2.sln">
<Properties>Configuration=Debug</Properties>
</ProjectToBuild>
<ProjectToBuild Include="$(SolutionsPath)\UI\Solution3.sln">
<Properties>Configuration=Debug</Properties>
</ProjectToBuild>
</ItemGroup>
<MSBuild Projects="#(ProjectToBuild)"
Targets="Rebuild"
Properties="Platform=Any CPU"/>
</Target>
I note there is a similar question, MSBuild task - Build fails because one solution being built in release instead of debug, but that is specific to TFS and Teambuild. I am talking pure MSBuild with a simple project file created from scratch.
How can I fix this problem?

Regarding the question of spelling of platform any cpu, it turns out there is an issue, already reported elsewhere here on StackOverflow and Microsoft. It affects MSBuild in general and the entire issue of Platform documentation is omitted in my dotnet v3.5 MSBuild /help. So perhaps this will help someone!
Links
"AnyCPU" vs "Any CPU" in TFS 2010
MSBuild inconsistent platform for "Any CPU" between solution and project
Closed as Won't Fix
Type: Bug
ID: 503935
Opened: 10/26/2009 1:29:12 PM
Access Restriction: Public
0 Workaround(s)
5 User(s) can reproduce this bug
The MSBuild Platform property has a different value for Any CPU depending upon whether you are building a solution or building a project.
- for Solution - use Platform="Any CPU" - with space
- for Project - use Platform="AnyCPU" - without space

OK I have found the issue. Nothing related to MSBuild, but instead the solution being built. Posting to save someone else the heartache.
For whatever reason the Debug configuration was configured within the solution like so:
alt text http://www.freeimagehosting.net/uploads/cad0bdf1c0.jpg
So MSBuild was only doing what it was told too...

I was getting this same error. The solution was to explicitly specify the target platform with:
msbuild.exe /p:Platform="Any CPU"
This only started happening since I upgraded to windows 7, so I guess it is something to do with that.

Have you tried running with /v:diag?
Also, aside: I think you want "AnyCPU" (no space).

Related

MSBuild ignores changes inside *.wpp.target

I have following *.wpp.target file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
ExcludeCustomFilesOrFolders;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
<Target Name="ExcludeCustomFilesOrFolders" BeforeTargets="ExcludeFilesFromPackage">
<ItemGroup>
<ExcludeFromPackageFolders Include="$(MSBuildProjectDirectory)\Media" />
</ItemGroup>
<Message Text="Custom Exclude From %0D Folders: #(ExcludeFromPackageFolders)%0D Files: #(ExcludeFromPackageFiles)" Importance="high"/>
</Target>
If I run it for the first time out of visual studio 17 Media folder is ignored and not published.
After when I comment the line with ExcludeFromPackageFolders node and publish again Media folder is still ignored. It seems that visual studio or msbuild does not refresh changes made inside *.wpp.target file. Do I miss here something or is VS or MSbuild just buggy?
Can you try to add /PROFILE to the linker option? Might fix the problem: https://developercommunity.visualstudio.com/content/problem/136703/wpp-trace-missing-from-pdb-files-in-vs-2017.html
You have to restart visual studio and reload solution everytime you change it. VS caches it.

Stopping Post Build events on project when building directly from MSBuild

I have a project which has some post build events that do some copying around for other projects. I unfortunately cannot change that, and have been asked to write a build script for use on a CI server.
Problem is that the post build steps run off the debug/release bin folders and I compile through the build script to a different folder. So one solution would be to let the project build as is, and then manually copy all files from the bin folders to the output folder I am using. However that feels like a bit of a hack, so I was wondering if there is a way for an MSBuild task to tell the solution it is building to ignore PostBuild events, I believe you could set a property PostBuildEvent='' but it didnt seem to stop them from happening...
Here is an example of the build script target:
<Target Name="Compile" DependsOnTargets="Clean;">
<MSBuild Projects="$(SourceDirectory)\SomeSolution.sln"
Properties="Configuration=Release; OutputPath=$(CompilationDirectory); PostBuildEvent=''" />
</Target>
Anyone had to do anything similar before?
To disable all PostBuildEvents, set the CustomAfterMicrosoftCommonTargets to C:\PostBuild.config (or whatever you name the file) and have PostBuild.config to be:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="PostBuildEvent"/>
</Project>
Add /p:CustomAfterMicrosoftCommonTargets="C:\PostBuild.config" to your msbuild command line
Or update your MsBuild task properties:
<MsBuild Projects="$(ProjectTobuild)" Properties="Configuration=$(Configuration);Platform=$(Platform);CustomAfterMicrosoftCommonTargets='C:\PostBuild.config'" Targets="Build"/>
To disable PostBuildEvents at project level for MSBuild, simply put these codes inside .csproj:
<Target Name="BeforeBuild">
<PropertyGroup>
<PostBuildEvent Condition="'$(BuildingInsideVisualStudio)' == 'false' Or '$(BuildingInsideVisualStudio)' != 'true'"></PostBuildEvent>
</PropertyGroup>
</Target>

Specifying assembly version of all projects within a web deployment wdproj script

I have a .wdproj Web Deployment Project created with VS2010 that contains references to other class libraries, like this:
<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ProjectReference Include="..\Path\Proj1.csproj">
<Project>{GUID-HERE}</Project>
<Name>Proj1</Name>
</ProjectReference>
<ProjectReference Include="..\Path\Proj2.csproj">
<Project>{GUID-HERE}</Project>
<Name>Proj2</Name>
</ProjectReference>
There are lots of these. I want to be able to run msbuild /t:Rebuild /p:Configuration=Release and have all the assemblies of all the included projects compiled at a specified version. Nothing fancy just static like 2.5.6.0 and specified once in the wdproj file. I dont want to open 30 files manually.
I have looked at MSBuild Community Task and MSBuildExtension Pack and can not get anything to work. The build runs ok without errors.
Anyone have an example of how this can be done?
This is an attempt with MSBuild Extensions (adapted from the sample included) that doesn't work:
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.VersionNumber.targets"/>
<Target Name="Build">
<MSBuild.ExtensionPack.Framework.AssemblyInfo
ComVisible="true"
AssemblyInfoFiles="VersionInfo.cs"
AssemblyFileMajorVersion="2"
AssemblyFileMinorVersion="5"
AssemblyFileBuildNumber="6"
AssemblyFileRevision="0"
/>
</Target>
MSBuild is definately looking at the MSBuild.ExtensionPack.Framework.AssemblyInfo element because if the attribute names are incorrect the build will fail. This builds ok but none of the versions on the referenced assemblies are changed. The version numbers on the ASP.NET page assemblies from the website are all 0.0.0.0.
Are you maybe missing to specify the CodeLanguage and OutputFile attributes?
I think the AssemblyInfo task is intended to generate (replace) a source file prior to compiling.

MSBuild doesn't respect PublishUrl property for my ClickOnce app

I'm trying to make a batch file to publish the few ClickOnce application we have in one click. I'm using msbuild for that, and as an example the below command line shows how I'm doing it:
msbuild
MyApp.sln
/t:Publish
/p:Configuration=Release
/p:PublishUrl="C:\Apps\"
/v:normal > Log.txt
(wrapped for easier reading)
when I run the above command it builds and publish the application in the release directory, i.e. bin\release! Any idea why msbuild doesn't respect PublishUrl property in my example above?
PS: I tried also different combinations including remove 'Configuration', use 'Rebuild' and 'PublishOnly' as targets, and remove the the quotation marks but without any success.
You are setting the wrong property. Try PublishDir instead.
You can pass it into MSBuild as you are or you can set it in the project file (or maybe the sln file too, not sure I always use the project file.) like this
<PropertyGroup>
<PublishDir>C:\Dev\Release\$(BuildEnvironment)\</PublishDir>
</PropertyGroup>
I've just done a few blog posts on MsBuild and ClickOnce stuff, check it out you 'should' find them useful...
Some features are done by Visual-Studio and not by the MSBuild-script. So the click-once-deployment behaves differently when it's executed from the command-line.
The ApplicationRevision isn't increased with every build. This works only when is exectued from Visual Studio
In in somecases, the PublishUrl isn't used. Quote from MSDN:
For example, you could set the PublishURL to an FTP path and set the InstallURL to a Web URL. In this case, the PublishURL is only used in the IDE to transfer the files, but not used in the command-line builds. Finally, you can use UpdateUrl if you want to publish a ClickOnce application that updates itself from a separate location from which it is installed.
I've created a special MSBuild-file which does this things. It runs the publish-target and copies then the files to the right location.
An example of the build-file, as requested by alhambraeidos. It basically runs the regular VisualStudio-build and then copies the click-once data to the real release folder. Note that removed some project-specific stuff, so it's maybe broken. Furthermore it doesn't increase the build-number. Thats done by our Continues-Build-Server:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Publish" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- the folder of the project to build -->
<ProjLocation>..\YourProjectFolder</ProjLocation>
<ProjLocationReleaseDir>$(ProjLocation)\bin\Release</ProjLocationReleaseDir>
<ProjPublishLocation>$(ProjLocationReleaseDir)\app.publish</ProjPublishLocation>
<!-- This is the web-folder, which provides the artefacts for click-once. After this
build the project is actually deployed on the server -->
<DeploymentFolder>D:\server\releases\</DeploymentFolder>
</PropertyGroup>
<Target Name="Publish" DependsOnTargets="Clean">
<Message Text="Publish-Build started for build no $(ApplicationRevision)" />
<MSBuild Projects="$(ProjLocation)/YourProject.csproj" Properties="Configuration=Release" Targets="Publish"/>
<ItemGroup>
<SchoolPlannerSetupFiles Include="$(ProjPublishLocation)\*.*"/>
<SchoolPlannerUpdateFiles Include="$(ProjPublishLocation)\Application Files\**\*.*"/>
</ItemGroup>
<Copy
SourceFiles="#(SchoolPlannerSetupFiles)"
DestinationFolder="$(DeploymentFolder)\"
/>
<Copy
SourceFiles="#(SchoolPlannerUpdateFiles)"
DestinationFolder="$(DeploymentFolder)\Application Files\%(RecursiveDir)"
/>
<CallTarget Targets="RestoreLog"/>
</Target>
<Target Name="Clean">
<Message Text="Clean project:" />
<MSBuild Projects="$(ProjLocation)/YourProject.csproj" Properties="Configuration=Release" Targets="Clean"/>
</Target>
</Project>
I'll put in my 2 cents, this syntax seems to work (right or wrong):
/p:publishUrl="C:\\_\\Projects\\Samples\\artifacts\\Web\\"
For me, the soultion was to escape the path.
Instead of:
/p:PublishUrl="C:\Apps\"
Put:
/p:PublishUrl="C:\\Apps\\"

Conditional compilation with automated builds in Visual Studio

Here's what I'm trying to do:
A single build script
That script builds two executables from the same Visual Studio project.
The first compiled .exe has a small amount of code disabled.
The other compiled .exe has everything enabled.
I've been reading up on conditional compilation and that takes care of my needs as far as enabling/disabling blocks of code.
I just can't figure out how to control conditional compilation from a build script using msbuild.
Is there a way to manipulate conditional compilation variables from a build script or some other way to accomplish what I'm trying to do?
Use build configurations in your project file. Set the parameters in a PropertyGroup that is optionally included based on the configuration. The configuration can then also define the output path for the two different versions of the assembly.
For the version that needs to remove some code use a configuration that includes the PropertyGroup.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CompiledOutDebug|AnyCPU' ">
<DefineConstants>$(DefineConstants);MY_CONDITIONAL_COMPILATION_CONSTANT</DefineConstants>
</PropertyGroup>
Then use an MSBuild script that calls the project MSBuild script twice and uses the Properties attribute of the MSBuild task to specify the configuration to build:
<Target Name="Build">
<MSBuild Projects="MyProject.csproj;"
Targets="Build"
Properties="Configuration=Release" />
<MSBuild Projects="MyProject.csproj"
Targets="Build"
Properties="Configuration=CompiledOutDebug" />
</Target>
Hamish beat me to it.
Here's an alternate solution using the same concepts:
At the command line:
msbuild -t:Clean
msbuild
CopyOutputDirForWithoutDefine.cmd
msbuild -t:Clean
msbuild -property:DefineConstants=MY_CONDITIONAL_COMPILE_CONSTANT
CopyOutputDirForWithDefine.cmd
The 1st and 3rd 'msbuild -t:Clean' ensures that you don't have left over turds from previous builds. The 2nd 'msbuild' builds without the conditional define, while the 4rth builds with the conditional define.
If the above are just a couple on shot items, then a batch file maybe enough. I recommend learning a bit of MSBuild and actually scripting everything in a MSBuild file as Hamish has done.
If you don't want to create a separate target for the two compilations, you can do it by specifying the conditional define in the DefineConstants property when you call the build the second time:
<Target Name="Build">
<MSBuild Projects="MyProject.csproj;"
Targets="Build"
Properties="Configuration=Debug" />
<MSBuild Projects="MyProject.csproj"
Targets="Build"
Properties="Configuration=Debug;
AssemblyName=$(AssemblyName)_Conditional;
DefineConstants=$(DefineConstants);CONDITIONAL_DEFINE" />
</Target>
Note that if you do it this way, you need to also overwrite the AssemblyName, otherwise your second build might pick intermediate files from the first build.
You should also look at the MSBuild task docs on MSDN, there are some interesting tidbits there.