Command line MSBuild not exluding Debug libraries - msbuild

So I have build a UWP application which I have built an .appxupload package through Visual Studio and submitted it to the store and it has been accepted to the store fine.
I am now trying to use Visual Studio Online to Automate my build process.
I am building my project in a new configuration I have defined called AppStore that looks like the following:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'AppStore|AnyCPU'">
<OutputPath>bin\AppStore\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
And my Command line arguments for the Automated build are:
/p:Configuration=AppStore;AppxBundle=Always;AppxBundlePlatforms="x86|x64|ARM";AppxPackageDir="$(Build.BinariesDirectory)\AppxPackages\\";UapAppxPackageBuildMode=StoreUpload
This then created my .appxupload package on request which was great.. BUT... when I uploaded to the store I get the following:
Debug configuration
Error Found: The debug configuration test detected the following errors:
The binary MyApp.Logging.dll is built in debug mode.
The binary MyApp.Reports.dll is built in debug mode.
The binary MyApp.DataAccess.dll is built in debug mode.
The binary MyApp.Business.dll is built in debug mode.
The binary MyApp.Core.dll is built in debug mode.
Are my MsBuild arguments incorrect?
Update
this is the command MSBuild is running:
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" "C:\agent\_work\1\s\MyApp\MyApp\MyApp.UWP\MyApp.UWP.csproj" /nologo /nr:false /t:"Clean" /dl:CentralLogger,"C:\agent\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.118.0\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll";"RootDetailId=ebe5f0fb-1da0-4f6b-aa54-d80c73ac3060|SolutionDir=C:\agent\_work\1\s\MyApp\MyApp\MyApp.UWP"*ForwardingLogger,"C:\agent\_work\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.118.0\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll" /p:Configuration=AppStore;AppxBundle=Always;AppxBundlePlatforms="x86|x64|ARM";AppxPackageDir="C:\agent\_work\1\b\AppxPackages\\";UapAppxPackageBuildMode=StoreUpload /p:configuration="AppStore" /p:VisualStudioVersion="15.0" /p:_MSDeployUserAgent="VSTS_7c0e42bd-65b9-486e-9338-1c87ca14bb55_build_3_1182"
It seems to produce x86 in Release mode and x64 and ARM in debug and thats where my app fails Windows Certification Checks

Refer to these steps to change configuration:
Right click solution file in VS > Configuration Manager
Select AppStore configuration
Change configurations of MyApp.Logging, MyApp.Reports, MyApp.DataAccess … (e.g. release)

Related

Publish web project from JetBrains Rider

I am giving Rider a try, and so far, quite like it.
One feature I use in Visual Studio quite often is right click on a web project and publish to our testing server.
I cannot find a similar option in Rider, so what I have done is, create a run configuration, with the following settings:
Exe path: C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/MSBuild/15.0/Bin/amd64/msbuild.exe
Arguments: MySolution.sln /m /p:DeployOnBuild=True /p:PublishProfile=My-Project "/p:platform=Any CPU" /p:configuration=Release /p:VisualStudioVersion=15.0 /p:Password=****
Working Directory: C:\SolutionFolder
When I want to publish, I select it from the drop-down and click run.
This works 100%.
My question is, is this the best way to do it, sans setting up a CI pipeline? Am I missing an option or setting in the IDE?
As of June 2018, Rider doesn't have UI for publishing.
There is a feature request which you can vote for, once logged in YouTrack.
As a workaround, one can create a '.NET Executable' configuration like you did, and run it when you want to publish your project.
More detailed instructions follows:
Run > Edit Configuration
Add new configuration > .NET Executable
Name = your project name
Exe path = path to your MSBuild (for example C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/MSBuild/15.0/Bin/amd64/MSBuild.exe)
Program arguments = YourSolution.sln /t:"Your_Project" /p:PublishProfile=YourPublishProfile.pubxml /p:Configuration=Debug /p:DeployOnBuild=true /m
Working directory = C:/path/to/solution/dir/
Notes:
the project publish profile is usually located in the project folder, under Properties/PublishProfiles. If you don't have one you can start with the example reported below;
you need to replace the dots (.) in the project name with underscores (_). In the example above Your.Project was passed as Your_Project;
you can specify a different publishing directory, if not already specified in the publish profile, by adding the argument /p:PublishDir="C:/path/to/publish/dir/";
if you don't have Visual Studio installed on your machine, you can use the MSBuild bundled with the Build Tools for Visual Studio 2017.
Example of publish profile:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>..\YourPublishDirectory</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
<ExcludeFilesFromDeployment>bin\*.dll.config</ExcludeFilesFromDeployment>
</PropertyGroup>
</Project>
Latest versions of Rider support publishing via UI. If you don't have Visual Studio installed on your machine, make sure the web project has Build.Microsoft.VisualStudio.Web.targets nuget package installed.

How or why is MSBuild choosing the x64 platform when I don't specify it instead of AnyCPU?

I'm running msbuild.exe via Rake from a regular PowerShell console. This is the command as printed from a diagnostic level run
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" "D:/Projects/machine.specifications/Source/Machine.Specifications/Machine.Specifications.csproj31881140" /maxcpucount /target:Build /verbosity:diagnostic /property:Configuration=Debug /property:TrackFileAccess=false /property:BuildInParallel=false /property:BuildRunner=Rake
And the build is failing because msbuild is picking x64 as the Platform.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(483,9): error : The OutputPath property is not set for project 'Machine.Specifications.csproj37103470'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='Debug' Platform='X64'. You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn't exist for this project.
I'm not passing it in on the command line (or from the script). The csproj has a default configuration
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
and two specific configurations
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
So, I expected the AnyCPU platform to be selected. But, for some reason, something is picking or sending in x64. I don't think the Rake system is a problem here, I've seen this behavior before on raw cmd line calls to msbuild (but I haven't documented them).
I'm on 64-bit Windows 7, calling msbuild 4.0. I don't know if that's relevant.
I am loading the 64-bit Visual Studio tools (C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64) using Invoke-BatchFile in my PowerShell profile. Could that be the culprit?
Why would msbuild deliberately choose x64 anyway? The 32-bit version doesn't choose x86 for you.
*1: The PowerShell console is at %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
*2: I'm running the MSpec build (here's the rakefile and the msbuild call)
When you launch Visual Studio x64 command window, it sets an environment variable :
Platform=X64
This is a difference from the 32 bit command window, where this environment variable is not defined, and MSBuild then uses the conditional logic to use default platform.
You can either remove the Platform environment variable in your batch file, or pass in explicit Platform property as a parameter to MSBuild.

Why Unpublishable?

We have a solution that contains 17 projects.
Solution has several configurations such as Debug, Release, Test, Publish and etc.
Also team project has several build definitions, each one is specialized for a configuration.
We use Release configuration build for nightly builds and Publish configuration build for publish and deployment.
So these build definitions, build same source code. But there is a problem...
Our nightly build creates obj\Release directories for each project but publish build doesn't.
Because of this publish build doesn't create server publish package.
When I looked to the build logs I saw the differences like below.
Nightly build - Release configuration (for each project)
PrepareForBuild:
Creating directory "obj\Release\".
Publish build - Publish configuration (for each project)
_DeploymentUnpublishable:
Skipping unpublishable project.
But I couldn't understand why?
Which flag controls this?
We are using TFS 2010, so Team Build 2010.
Try adding the following deployment settings to the project file inside the property group for the build configuration you want to publish:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<FilesToIncludeForPublish>OnlyFilesToRunTheApp</FilesToIncludeForPublish>
<DeployOnBuild>true</DeployOnBuild>
<DeployTarget>Package</DeployTarget>
<PackageAsSingleFile>true</PackageAsSingleFile>
</PropertyGroup>
I was getting a similar error on a web project's CI build. Adding the deployment settings to the web.csproj file corrected it.

How do I specify the platform for MSBuild?

I am trying to use MSBuild to build a solution with a specified target platform (I need both binaries, x86 and x64). This is how I tried it:
C:\WINDOWS\Microsoft.NET\Framework\v3.5>MsBuild SolutionPath\Solution.sln /t:Rebuild /p:Configuration=Release /p:Platform="x86"
However the build always fails if the platform is different from "Any CPU". What am I doing wrong?
This is the while output MSBuild prints:
C:\WINDOWS\Microsoft.NET\Framework\v3.5>MsBuild
SolutionPath\Solution.sln /t:Rebuild
/p:Configuration=Release
/p:Platform="x86" Microsoft (R) Build
Engine Version 3.5.30729.1 [Microsoft
.NET Framework, Version
2.0.50727.3082] Copyright (C) Microsoft Corporation 2007. All rights
reserved.
Build started 1.7.2010 8:28:10.
Project "SolutionPath\Solution.sln" on
node 0 (Rebuild targe t(s)).
SolutionPath\Solution.sln : error
MSB4126: The specified sol ution
configuration "Release|x86" is
invalid. Please specify a valid
solution c onfiguration using the
Configuration and Platform properties
(e.g. MSBuild.exe Solution.sln
/p:Configuration=Debug
/p:Platform="Any CPU") or leave those
prope rties blank to use the default
solution configuration. Done Building
Project "SolutionPath\Solution.sln"
(Rebuild t arget(s)) -- FAILED.
Build FAILED.
"SolutionPath\Solution.sln" (Rebuild
target) (1) ->
(ValidateSolutionConfiguration target)
-> SolutionPath\Solution.sln : error MSB4126: The specified s olution
configuration "Release|x86" is
invalid. Please specify a valid
solution configuration using the
Configuration and Platform properties
(e.g. MSBuild.ex e Solution.sln
/p:Configuration=Debug
/p:Platform="Any CPU") or leave those
pro perties blank to use the default
solution configuration.
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.03
If I try to build it for x86/x64 with devenv it works perfectly, however I am trying to set up a build server without installing all the necessary versions of Visual Studio. By the way, if there is a better free tool (that supports .NET framework 4) out there, I'd love to hear about it.
In MSBuild or Teamcity use command line
MSBuild yourproject.sln /property:Configuration=Release /property:Platform=x64
or use shorter form:
MSBuild yourproject.sln /p:Configuration=Release /p:Platform=x64
However you need to set up platform in your project anyway, see the answer by Julien Hoarau.
If you want to build your solution for x86 and x64, your solution must be configured for both platforms. Actually you just have an Any CPU configuration.
How to check the available configuration for a project
To check the available configuration for a given project, open the project file (*.csproj for example) and look for a PropertyGroup with the right Condition.
If you want to build in Release mode for x86, you must have something like this in your project file:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
...
</PropertyGroup>
How to create and edit the configuration in Visual Studio
(source: microsoft.com)
(source: msdn.com)
(source: msdn.com)
How to create and edit the configuration (on MSDN)
If you're trying to do this from the command line, you may be encountering an issue where a machine-wide environment variable 'Platform' is being set for you and working against you. I can reproduce this if I use the VS2012 Command window instead of a regular windows Command window.
At the command prompt type:
set platform
In a VS2012 Command window, I have a value of 'X64' preset. That seems to interfere with whatever is in my solution file.
In a regular Command window, the 'set' command results in a "variable not defined" message...which is good.
If the result of your 'set' command above returns no environment variable value, you should be good to go.
Hopefully this helps someone out there.
For platform I was specifying "Any CPU", changed it to "AnyCPU" and that fixed the problem.
msbuild C:\Users\Project\Project.publishproj /p:Platform="AnyCPU" /p:DeployOnBuild=true /p:PublishProfile=local /p:Configuration=Debug
If you look at your .csproj file you'll see the correct platform name to use.
For VS2017 and 2019... with the modern core library SDK project files, the platform can be changed during the build process. Here's an example to change to the anycpu platform, just before the built-in CoreCompile task runs:
<Project Sdk="Microsoft.NET.Sdk" >
<Target Name="SwitchToAnyCpu" BeforeTargets="CoreCompile" >
<Message Text="Current Platform=$(Platform)" />
<Message Text="Current PlatformTarget=$(PlatformName)" />
<PropertyGroup>
<Platform>anycpu</Platform>
<PlatformTarget>anycpu</PlatformTarget>
</PropertyGroup>
<Message Text="New Platform=$(Platform)" />
<Message Text="New PlatformTarget=$(PlatformTarget)" />
</Target>
</Project>
In my case, I'm building an FPGA with BeforeTargets and AfterTargets tasks, but compiling a C# app in the main CoreCompile. (partly as I may want some sort of command-line app, and partly because I could not figure out how to omit or override CoreCompile)
To build for multiple, concurrent binaries such as x86 and x64: either a separate, manual build task would be needed or two separate project files with the respective <PlatformTarget>x86</PlatformTarget> and <PlatformTarget>x64</PlatformTarget> settings in the example, above.
When you define different build configurations in your visual studio solution for your projects using a tool like ConfigurationTransform, you may want your Teamcity build, to build you a specified build configuration. You may have build configurations e.g., Debug, Release, Dev, UAT, Prod etc defined. This means, you will have MSBuild Configuration transformation setup for the different configurations. These different configurations are usually used when you have different configurations, e.g. different database connection strings, for the different environment. This is very common because you would have a different database for your production environment from your playground development environment.
They say a picture is worth a thousand words, please see the image below how you would specify multiple build configurations in Teamcity.
In the commandline input text box, specify as below
/p:OutputPath=Publish;Configuration=Dev
Here, I have specified two commandline build configurations/arguments OutputPath and build Configuration with values Publish and Dev respectively, but it could have been, UAT or Prod configuration. If you want more, simply separate them by semi-colon,;
There is an odd case I got in VS2017, about the space between ‘Any’ and 'CPU'.
this is not about using command prompt.
If you have a build project file, which could call other solution files. You can try to add the space between Any and CPU, like this (the Platform property value):
<MSBuild Projects="#(SolutionToBuild2)" Properties ="Configuration=$(ProjectConfiguration);Platform=Any CPU;Rerun=$(MsBuildReRun);" />
Before I fix this build issue, it is like this (ProjectPlatform is a global variable, was set to 'AnyCPU'):
<MSBuild Projects="#(SolutionToBuild1)" Properties ="Configuration=$(ProjectConfiguration);Platform=$(ProjectPlatform);Rerun=$(MsBuildReRun);" />
Also, we have a lot projects being called using $ (ProjectPlatform), which is 'AnyCPU' and work fine. If we open proj file, we can see lines liket this and it make sense.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
So my conclusion is,
'AnyCPU' works for calling project files, but not for calling solution files,
for calling solution files, using 'Any CPU' (add the space.)
For now, I am not sure if it is a bug of VS project file or MSBuild.
I am using VS2017 with VS2017 build tools installed.
In Visual Studio 2019, version 16.8.4, you can just add
<Prefer32Bit>false</Prefer32Bit>

Overriding MSBuildExtensionsPath in the MSBuild task is flaky

This is already cross-posted at MS Connect:
https://connect.microsoft.com/VisualStudio/feedback/details/560451
I am attempting to override the property $(MSBuildExtensionsPath) when building a solution containing a C# web application project via msbuild. I am doing this because a web application csproj file imports the file "$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets". This file is installed by Visual Studio to the standard $(MSBuildExtensionsPath) location (C:\Program Files\MSBuild). I would like to eliminate the dependency on this file being installed on the machine (I would like to keep my build servers as "clean" as possible). In order to do this, I would like to include the Microsoft.WebApplication.targets in source control with my project, and then override $(MSBuildExtensionsPath) so that the csproj will import this included version of Microsoft.WebApplication.targets. This approach allows me to remove the dependency without requiring me to manually modify the web application csproj file.
This scheme works fine when I build my solution file from the command line, supplying the custom value of $(MSBuildExtensionsPath) at the command line to msbuild via the /p flag. However, if I attempt to build the solution using the MSBuild task in a custom msbuild project file (overriding MSBuildExtensionsPath using the "Properties" attribute), it fails because the web app csproj file is attempting to import the Microsoft.WebApplication.targets from the "standard" Microsoft.WebApplication.targets location (C:\Program Files\MSBuild). Notably, if I run msbuild using the "Exec" task in my custom project file, it works. Even more notably, the FIRST time I run the build using the "MSBuild" task AFTER I have run the build using the "EXEC" task (or directly from the command line), the build works.
Has anyone seen behavior like this before? Am I crazy? Is anyone aware of the root cause of this problem, a possible workaround, or whether this is a legitimate bug in MSBuild?
Steps to Reproduce:
1) Create a new empty solution in MSVS 2008 (Fake.sln)
2) Add a new C# web application to the solution (WebApplication1.csproj)
3) Close MSVS
4) Copy the contents of "C:\Program Files\MSBuild\" to a directory called "MSBuildExtensions" in the directory containing your solution.
5) rename the directory "C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications" so that WebApplication1.csproj will not be able to import Microsoft.WebApplication.targets from that location.
6) Create a custom MSBuild project file called "TestBuild.proj" in the same directory as the solution. It should have the following content:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="BuildMSBuild">
<PropertyGroup>
<MSBuildExtensionsPath>$(MSBuildProjectDirectory)\MSBuildExtensions\</MSBuildExtensionsPath>
<BuildThis>Fake.sln</BuildThis>
</PropertyGroup>
<Target Name="BuildMSBuild">
<MSBuild Projects="$(BuildThis)" Properties="MSBuildExtensionsPath=$(MSBuildExtensionsPath);" Targets="Clean" />
<MSBuild Projects="$(BuildThis)" Properties="MSBuildExtensionsPath=$(MSBuildExtensionsPath);"/>
</Target>
</Project>
7) execute "msbuild TestBuild.proj" from a MSVS command prompt (note: the build may succeed the first time, but will fail if you run more than once)
Did you try setting the environment variable MSBuildExtensionPath in the CMD prompt and then running your build?
For example:
C:\> SET MSBuildExtensionsPath=C:\My\MSBuild\Extensons
Then on this project file:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Message Text='MSBuildExtensionsPath="$(MSBuildExtensionsPath)"' />
</Target>
</Project>
you will get the following output:
c:\Users\chuckeng\Desktop\ConsoleApplication1>"C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe" my.proj
Microsoft (R) Build Engine Version 3.5.30729.4926
[Microsoft .NET Framework, Version 2.0.50727.4927]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 6/25/2010 1:04:05 PM.
Project "c:\my.proj" on node 0 (default targets).
MSBuildExtensionsPath="C:\My\MSBuild\Extensons"
Done Building Project "c:\my.proj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.03
This works from v4.0 as well. Although, support is generally better in v4.0 for things like this. And, v4.0 is 100% backward compatible (bugs not withstanding). So, you can build your v3.5 and prior projects with v4.0. Just select ToolsVersion 3.5.
msbuild my.proj /tv:3.5
Hope this helps...
Chuck England
Visual Studio
Program Manager - MSBuild
This is a bug in MSBuild 3.5 but it is fixed in MSBuild 4.
If you can, switch to MSBuild 4 (you still can compile your 3.5 projects), otherwise you'll have to override the property in the project file.
It works fine if you override MSBuildExtensionsPath directly in the web app .csproj file.
<PropertyGroup>
<MSBuildExtensionsPath>C:\Users\madgnome\Desktop\msbuild</MSBuildExtensionsPath>
<!-- It works too with relative path -->
<!--<MSBuildExtensionsPath>..\msbuild</MSBuildExtensionsPath>-->
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
Don't know if this might help anyone in the future, but I was able to use the following at the top of my file and it works as I would expect in both 32 and 64 bit build environments.
<PropertyGroup>
<MSBuildExtensionsPath Condition=" '$(MSBuildExtensionsPath64)' != '' ">$(MSBuildExtensionsPath64)</MSBuildExtensionsPath>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>