.NET Core RuntimeIdentifier vs TargetFramework - asp.net-core

Can someone explain the purpose of this two in csproj file (VS2017):
<TargetFramework>netstandard1.6</TargetFramework>
<RuntimeIdentifier>win7</RuntimeIdentifier>
I just migrated from VS2015 and now can't publish my web api because it looks I should use only one target framework. In addition I can't specify multiple RIDs.
All these changed things make me frustrated. Nothing works from scratch, should overcome something over and over.
I just want developing my web-api on windows, run xUnit tests here and then deploy web-api to run on linux (ubuntu) server.
What I should put in both parameters in csproj ?
Links with good explanation is highly appreciated.
Update1
I have web api with referenced .net core libraries. Everything where migrated from VS2015. Now in root project I have
<TargetFrameworks>netcoreapp1.1;net461</TargetFrameworks>. When I publish via VS2017 I got error:
C:\Program
Files\dotnet\sdk\1.0.3\Sdks\Microsoft.NET.Sdk\buildCrossTargeting\Microsoft.NET.Sdk.targets(31,5):
error : The 'Publish' target is not supported without specifying a
target framework. The current project targets multiple frameworks,
please specify the framework for the published application.
But I have specified target framework in publish as netcoreapp1.1.
OK. Then I updated my csproj with <PropertyGroup Condition="$(TargetFramework)'=='netcoreapp1.1'">
<RuntimeIdentifier>ubuntu.16.10-x64</RuntimeIdentifier>
</PropertyGroup> as suggested below.
But now I even can't build app, get error:
5>C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.targets(92,5):
error : Assets file '\obj\project.assets.json' doesn't
have a target for '.NETCoreApp,Version=v1.1/ubuntu.16.10-x64'. Ensure
you have restored this project for TargetFramework='netcoreapp1.1' and
RuntimeIdentifier='ubuntu.16.10-x64'.
I just want develop with VS2017 at windows 8.1/windows7 and deploy to ubuntu 16.10.
What I'm doing wrong ?
Update2
I have 8 projects in solution. 3 of them are xUnit tests. Thus we have 5 projects. 4 of these 5 are class libraries and 1 is my web-app.
All 4 class libraries have this:
<TargetFrameworks>netstandard1.6;net461</TargetFrameworks>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
My web app:
<TargetFrameworks>netcoreapp1.1;net461</TargetFrameworks>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
How to publish my web-app ?

The <TargetFramework> (or <TargetFrameworks> when you want have multiple targets, such as net451, one or multiple netstandard1.x etc). Per <TargetFramework> / <TargetFrameworks> entry one set of assemblies will be created and located inside bin\Debug\<targetframeworkid>).
This is useful, when you want to use a different library in .NET Core (because the library you used only works with full .NET Framework such as 4.5.1) or remove this feature from i.e. .NET Core because it's unsupported.
It is used for both, building and NuGet restore. i.e. you can't use a net451 only library in a .NET Core project (netstandard 1.1 for example - but you can use netstandard1.1 in a net451 project).
<RuntimeIdentifier> / <RuntimeIdentifiers> on the other side is used for NuGet mainly. It tells NuGet which packages you need. For example if you want to target Linux, Mac and Windows, certain assemblies require native libraries (such as encryption. On windows CryptoAPI will be used, but on Linux and Mac you need OpenSSL). This includes non-managed dlls and *.so (Linux) files.
i.e. <RuntimeIdentifiers>win7-x64;win7-x86;ubuntu.16.10-x64</RuntimeIdentifiers> will make nuget restore packages for win7 (both x64 and x86) versions and x64 only for ubuntu. This is required, because when you work on windows you need to download these native libraries too so you deploy/package them with dotnet publish.
Here's a little catch though: When you have a full .NET Framework reference in <TargetFramework> or <TargetFrameworks>, then you must specify a single <RuntimeIdentifier> (singular, not plural <RuntimeIdentifiers>), otherwise you will get an error.
For example:
<PropertyGroup>
<TargetFrameworks>netstandard1.0;net451</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win7-x86;ubuntu.16.10-x64</RuntimeIdentifiers>
</PropertyGroup>
<!-- This entry will only be used for the .NET Framework 4.5.1 output -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net451'">
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>

RID is short for Runtime IDentifier. RIDs are used to identify target
operating systems where an application or asset (that is, assembly)
will run. They look like this: "ubuntu.14.04-x64", "win7-x64",
"osx.10.11-x64". For the packages with native dependencies, it will
designate on which platforms the package can be restored.
More in docs
First change to proper RID from win7 to win7-x64 or win7-x86. Next add other RID like ubuntu. For example:
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<RuntimeIdentifier>win7-x64;ubuntu.16.10-x64</RuntimeIdentifier>
</PropertyGroup>
Target framework looking good. For more read docs

Related

msbuild: how to build and run a console application within the build and have it write output files to the output directory of another project?

I have three projects, I will call them ProjectSource, ProjectProcessor and ProjectTarget
ProjectSource is a .NET Standard 2.0 library producing a DLL.
ProjectProcessor is a .NET Core 2.1 console library. ProjectProcessor has a project reference on ProjectSource. It loads the ProjectSource DLL and based on some types it finds in there generates some output files (lets just say they are documentation). The number of files it produces can change over time.
ProjectTarget is a .NET Framework 4.7.1 console application. It has a dependency on ProjectSource, but also needs to include the content output by ProjectProcessor.
All projects are our code so we could change them quite a bit.
My question is, what is the right way to get the content output files of ProjectProcessor written to the output directory of ProjectTarget?
Approach 1: One approach that did not work was to use project reference in ProjectTarget to ProjectProcessor. It produced a build error that a .NET Framework 4.7.1 console application referencing a .NET Core 2.1 console library. I wouldn't want all the project output copied anyway, just the generated documentation files. I did try a ProjectReference with ReferenceOutputAssembly="false" and OutputItemType="Content".
Approach 2: Another approach is to have a pre or post build step on ProjectTarget that calls the ProjectProcessor console application, passing in the
current target directory (of ProjectTarget). For example:
<PropertyGroup>
<PreBuildEvent>dotnet $(SolutionDir)projects\ProjectProcessor\$(OutDir)netcoreapp2.1\ProjectProcessor.dll $(TargetDir)</PreBuildEvent>
</PropertyGroup>
This works, with the unfortunat downside that it doesn't recognize when it needs to run (I think it'd always run?). If ProjectSource or
ProjectProcessor have code changes I'd like it to run again, but not otherwise. (based on MSBuild copy output from another project into the output of the current project)
Approach 3: Finally, googling led me to try adding a target like this:
<Target Name="GenerateDocumentationContent" BeforeTargets="AfterBuild">
<MSBuild Projects="..\ProjectProcessor\ProjectProcessor.csproj" BuildInParallel="false" Targets="Build">
<Output TaskParameter="TargetOutputs" ItemName="DocumentationOutputDir" />
</MSBuild>
<Exec Command="dotnet #(DocumentationOutputDir) $(TargetDir)"/>
</Target>
This builds the ProjectProcessor project as expected and calls the resulting console application with the right parameters. But it doesn't run in the case that ProjectTarget doesn't have changes and I want it to run if ProjectSource and ProjectProcessor have changes.

How to exclude some stylecop rule in visual studio 2013

I'm using visual studio 2013.
I install stylecop using NuGet Package follow these steps:
https://www.nuget.org/packages/StyleCop.MSBuild/
Previously when I using visual studio 2010, I usually put my custom rules set called Setting.StyleCop file to my solution or project.
How should I implement my custom rules set in VS 2013?
Settings.StyleCop still works as it did previously.
The StyleCop.MsBuild package performs a couple of actions:
1. Stores an instance of StyleCop.exe in the packages directory, this makes it portable between machines, build servers etc.. Namely \packages\StyleCop.MSBuild.4.7.49.1\tools this is pretty much the same you would get with installing it, but its not in program files.
2. Makes changes to the csproj, namely:
<Import Project="..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets" Condition="Exists('..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets'))" />
</Target>
All this basically does is point at the targets file so that it runs stylecop and adds in some requires for the package to be there before building.
What you need to do to use StyleCop.Settings
Copy it into the root of your solution, or the project file, then it should get picked up as usual. The easiest way is just to copy it from \packages\StyleCop.MSBuild.4.7.49.1\tools

How can I reset Visual Studio's publishing configuration to default?

I am just a hobbyist programmer so I am sorry if I am asking a question I should know the answer to. I searched for an answer, but never found it, so I thought I would join and post a question here.
I have some VB 2010 Express code I have written that I wished to deploy from my web page. I used Visual Studio's ClickOnce publishing system and was pleased with the results.
After a couple of versions published I went into the publisher's configuration manager to explore the options.
That was my, uhhh, mistake. I changed many things that I thought would make things nicer for the deployment but screwed up something because now all versions, even previously working versions no longer deploy correctly. If you click for a download and installation, the install starts but the installer complains that there is an error it wants to report to Microsoft.
Is there some way to reset the publish configuration back to it's starting values?
I am running VB on XP with Visual Studio 2010 Express.
I was able to reset the Publish settings for my actual project by comparing the content of the project files for two sample projects, one with publishing and the other one without and identifying which entries were added. I used the FC DOS command to output the differences to a text file (the file extensions were .csproj since mine was a C# project):
fc publish_project.csproj non_publish_project.csproj > diff.txt
I examined diff.txt and found what changed. Deleting the following entries from the real project file will reset the Publish option (do a backup first!):
<IsWebBootstrapper>true</IsWebBootstrapper>
<PublishUrl>ftp://ftpserver.com/</PublishUrl>
<Install>false</Install>
<InstallFrom>Web</InstallFrom>
<UpdateEnabled>true</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<InstallUrl>http://www.myproduct.net/project1/downloads/</InstallUrl>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>publish.htm</WebPage>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
...
<PropertyGroup>
<TargetZone>LocalIntranet</TargetZone>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
...
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
Copying the file ProjectName.vbproj from a very previous version took care of my problem.
I would presume that the other suggestion, creating a new project and copying it's file, should have the same result. Especially if you do not have previous versions.
When you publish, it creates a profile with all the configuration settings.
So, you just have to delete that profile.
Click on "Delete" and it should be reseted.

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"/>