TargetFramework
element.netcoreapp1.0
with netcoreapp1.0;net452
, as demonstrated in this .NET Blog post under the section Cross-targeting.netcoreapp1.0
and net452
as previously with the project.json format.Error occurs:
MSB4115 The "HasTrailingSlash" function only accepts a scalar value, but its argument "$(OutputPath)" evaluates to "bin\Debug\netcoreapp1.0;net452\" which is not a scalar value.
dotnet --info
output:
.NET Command Line Tools (1.0.0-preview3-004056)
Product Information:
Version: 1.0.0-preview3-004056
Commit SHA-1 hash: ccc4968bc3
Runtime Environment:
OS Name: Windows
OS Version: 10.0.14393
OS Platform: Windows
RID: win10-x64
@MartinJohns what happens if you change <TargetFramework>
to be plural, that is, <TargetFrameworks>
?
/cc @srivatsn @davkean @nguerrera
@blackdwarf
Error occurred while restoring NuGet packages: Invalid restore input. Invalid target framework 'unsupported'. Input files: name.csproj
And
RuntimeIdentifier must be set for .NETFramework executables. Consider RuntimeIdentifier=win7-x86 or RuntimeIdentifier=win7-x64.
@MartinJohns
The original issue was definitely using TargetFramework
to specify multiple frameworks instead of TargetFrameworks
(plural). The blog post has that right.
There are two other issues:
Currently, you do need to specify a RuntimeIdentifier if one of your targets is the full .NET Framework and you are building an exe. We are looking to improve this, see https://github.com/dotnet/sdk/issues/396
You must condition the .NETCoreApp package reference to only the netcoreapp1.0 build as the package is not compatible with net452. This is also being improved with https://github.com/dotnet/sdk/pull/450 which will make the package ref implicit and remove you from having to condition it yourself.
(1) above explains the RuntimeIdentifier error you're seeing.
(2) might be the "invalid restore input" you're seeing, but I'm seeing much clearer nuget errors on newer than RC bits:
One or more packages are incompatible with .NETFramework,Version=v4.5.2.
Package Microsoft.NETCore.App 1.0.1 is not compatible with net452 (.NETFramework,Version=v4.5.2).
For (1), here is how the main property group should look with both RuntimeIdentifer and TargetFrameworks set:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp1.0;net452</TargetFrameworks>
<RuntimeIdentifier>win7-x86</RuntimeIdentifier>
</PropertyGroup>
For (2), here is how the NETCore.App package ref should be conditioned
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp1.0'">
<PackageReference Include="Microsoft.NETCore.App">
<Version>1.0.1</Version>
</PackageReference>
</ItemGroup>
Let me know if you're still seeing errors after applying the above and please share the full .csproj that isn't working for you.
Hey @nguerrera,
I've indeed overlooked that there's a plural version in the blog post. Performing the changes that you mentioned allowed me to compile the project. But the way to this has been very rocky - I think the mistakes I made are very easily done and the tooling should at least inform me about solutions to the most common mistakes. That there's no schema (after the latest VS update) doesn't help much, and the XML editing experience is not great either (e.g. when I rename an opening tag it doesn't rename the closing tag).
Here's my updated csproj file:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp1.0;net452</TargetFrameworks>
<RuntimeIdentifier>win7-x86</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp1.0'">
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
</ItemGroup>
</Project>
It compiles fine, but when I press F5 I get the following error: "Unable to run your project. The "RunCommand" property is not defined."
Executing the net452 version works. Trying to execute the netcoreapp1.0 version fails:
C:\ConsoleApp2\bin\Debug\netcoreapp1.0>dotnet ConsoleApp2.dll
Could not find required library hostpolicy.dll in 1 probing paths:
C:\Users\Martin\.nuget\packages
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\ConsoleApp2\bin\Debug\netcoreapp1.0'.
Any advice on this?
Additionally, can you please expand on these questions?
RuntimeIdentifier
? Yes, I've tried RuntimeIdentifiers
. :-)I agree this is rocky and I apologize for that. FWIW, cross-targeting exe projects is significantly more complicated by these RID issues than cross-targeting libraries. We still need to do better on the docs and diagnostics, but let me try to answer your questions here.
Executing the net452 version works. Trying to execute the netcoreapp1.0 version fails:
The failure to load hostpolicy.dll is because we set an x86 RID for all outputs and we're trying to run on x64 dotnet.
Additionally, can you please expand how to define multiple RuntimeIdentifier? Yes, I've tried RuntimeIdentifiers. :-
For defining multiple RIDs, nuget restore understands RuntimeIdentifiers
(plural), but everything else requires that you specify one at a time. There is https://github.com/dotnet/sdk/issues/414 to reconcile this but in the meantime, you can get to a state that works for this project by specifying the full set of RIDs statically for restore and only setting a single RID when you're actually building for desktop.
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp1.0;net452</TargetFrameworks>
<RuntimeIdentifiers>win7-x86;win7-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net452'">
<!-- We must pick a single RID for desktop in order to consume native libraries. -->
<RuntimeIdentifier>win7-x86</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp1.0'">
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
</ItemGroup>
</Project>
From there:
Restore
dotnet restore
Build for all target frameworks
dotnet build
Run on desktop
dotnet run --framework net452
Run on core clr
dotnet run --framework netcoreapp1.0
Publish .NET Core standalone app for win7-x64
dotnet publish --framework netcoreapp1.0 --runtime win7-x64
Seems Update-Package
in NuGet(PowerShell) 4.0.0.2098
not work well with Condition
while NuGet(Vs Client)
works well, tested with VS 2017RC.2(15.0.26009.0).
Update-Package : Package Microsoft.NETCore.App 1.1.0 is not compatible with net45 (.NETFramework,Version=v4.5) / win7-x64. Package Microsoft.NETCore.App 1.1.0 supports: netcoreapp1.0 (.NETCoreApp,Version=v1.0)
@yyjdelete Please file a separate bug for that on https://github.com/nuget/home
The migration to MSBuild XML schema only give to us bad user experience, i not like vs2017.. i prefer vs2015 with json project format, easy and friendly. Nobody try to learn MSBuild schema before... the people are trying to do the things like with json project format and MSBuild is ugly.
@yyjdelete remove the NetCoreApp referecence and you should be able to compile and run it.
@SzymonSasin After that I was able to compile, and start server (dotnet run
) but it collapsed after http request.
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method MyReduxProject.Controllers.HomeController.Index (MyReduxProject) with arguments ((null)) - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor[1]
Executing ViewResult, running view at path /Views/Home/Index.cshtml.
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
User profile is available. Using 'C:\Users\roman\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action MyReduxProject.Controllers.HomeController.Index (MyReduxProject) in 4022.9624ms
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
An unhandled exception has occurred: Could not load file or assembly 'System.Diagnostics.DiagnosticSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
System.IO.FileLoadException: Could not load file or assembly 'System.Diagnostics.DiagnosticSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'System.Diagnostics.DiagnosticSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
<TargetFramework>net462</TargetFramework>
<RuntimeIdentifier>win7-x86</RuntimeIdentifier>
This was a bad UE for me. I had a single TF, then added one without knowing about the singular-plural situation. The exception coming back ...
C:\Program Files\dotnet\sdk\1.0.0-rc4-004530\Microsoft.Common.CurrentVersion.targets(123,17):
error MSB4115: The "HasTrailingSlash" function only accepts a scalar value, but its argument
"$(OutputPath)" evaluates to "bin\Debug\net451;netcoreapp1.1\" which is not a scalar value.
[PATH\KeyVaultConfigProviderSample\KeyVaultConfigProviderSample.csproj]
... is incredibly unhelpful. Although the phrase "only accepts a scalar value" makes perfect sense now, it's not easy to grok the problem from that.
I guess the suggestion here is to add a better error message? If so, this should be tracked in dotnet/sdk, since that is where the errors for this would come from.
My suggestion is to remove the distinction. Why have two element names for a single purpose? It just adds unnecessary complexity. The new format is supposed to be simplified.
My suggestion is to remove the distinction. Why have two element names for a single purpose? It just adds unnecessary complexity.
I was rather perplexed why it wasn't called <TargetFrameworks>
right from day one. I imagine it's an artifact from ancient times.
Ignoring the name confusion, let's imagine we remove the concept of "TargetFramework", what condition would you write to have an item (say a package or project reference) only apply to a single framework?
@blackdwarf can you move this to the SDK repo
Moved to dotnet/sdk#700. Closing this one.
@nguerrera,
The original issue was definitely using TargetFramework to specify multiple frameworks instead of TargetFrameworks (plural).
Can you consider to give hint in the error message or, even better, interprete TargetFramework with more than one target the same way as TargetFrameworks? Even it's correct from English point of view, it is not expected, that when you are changing content of an element, you have to change element name as well- see votes at http://stackoverflow.com/questions/43072097/build-errors-when-multi-targeting-in-csproj-file/43104496#43104496
Most helpful comment
My suggestion is to remove the distinction. Why have two element names for a single purpose? It just adds unnecessary complexity. The new format is supposed to be simplified.