Open mavasani opened 7 years ago
There are bunch of places in the SDK targets where we set RunCommand
property, but none of them seems to be doing it the target framework identifier is .NetStandard.
What does running on netstandard mean though? What CLR will it use to run?
Maybe we should just give a better error message here?
I agree. .NETStandard
just means that it is runnable on either Desktop
or .NETCore
. Without some additional context, nothing can actual get run (as the runtime bits well never be copied to the output by NuGet).
Yes, probably SDK or the compiler should report an error when attempting to build netstandard exe.
What's the eventual plan for building netstandard exes? Specify runtime in the project debug properties or when you set the startup project? Or disallow netstandard exes? I'm very curious because a similar conversation comes up around running netstandard tests when we talk about adding netstandard support. How do you specify which runtimes and framework versions to test on?
@jnm2, I would guess you target each framework you are meant to test/run on.
For example:
In my own projects all my libraries target .NETStandard: <TargetFramework>netstandard1.3</TargetFramework>
All of my tests and executables Multi-Target to Desktop and NETCore: <TargetFrameworks>net46;netcoreapp1.0</TargetFrameworks>
I then have logic to explicitly run the tests using the appropriate runner: once on Desktop and once more on NETCore.
@tannergooding Makes sense, so tests or exes targeting netstandard don't make a whole lot of sense and should probably error with a helpful diagnostic message telling you to multitarget to individual platform TFMs?
This is good to know because people are asking for netstandard support in NUnit. The guidance would then be: specify netcoreapp
, not netstandard
, and if you want to test multiple runtimes and versions then multitarget. Is that the best direction to take?
That is my opinion on it, but it might not be the right opinion 😄, someone like @srivatsn would be better suited as to the actual stance here.
This is good to know because people are asking for netstandard support in NUnit.
If the request is that the NUnit libraries support .NETStandard, then I see no reason why they shouldn't (and I thought they already did...). Users should be able to create Utility libraries that the actual test projects can reference, for example.
If the request is that the NUnit runner support executing .NETStandard libraries, then that depends on what the official stance is 😄
I think it makes sense for test projects to be able to target .NET Standard, and then have a way to tell the test runner which frameworks it should run the tests on. There's been some discussion of this previously, but I can't find it at the moment. Currently, the best solution is probably to multitarget your tests as @tannergooding suggests.
For this issue, I would prefer having a better error message rather than entirely preventing you from compiling an Exe targeting .NET Standard, if that's possible.
@tannergooding Yes, we're talking about NUnit runner support for actually executing netstandard libraries. NUnit does support executing netstandard libraries, but only netstandard1.6
and only on .NET Core.
An official documented stance that I can point people to would be fabulous. For example:
- Until we have a standard way to specify which runtimes and versions to execute netstandard tests against (maybe in the .csproj), do not target tests execution libraries to netstandard; instead, multitarget specific runtimes and versions
And keep everyone posted about where the execution runtimes and versions should be specified, and how the test runner will be able to determine what they are for each given test assembly. (Also I can see wanting to be able to test both x86 and x64 for things like performance or interop.) Should I start a new issue for documentation for test runners?
We just hit this for a net45
project in Microsoft/perfview#346.
Same for me netstandard1.6 + net47
Any news on this? How can we go around it?
@rjperes A workaround would be to add the "RunCommand" element to your csproj.
I use the following:
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<RunCommand>bin\$(Configuration)\$(AssemblyName).exe</RunCommand>
Some info on the two Append elements: https://www.tabsoverspaces.com/233608-stopping-msbuild-appending-targetframework-to-outputpath/
Where to specify runcommand? I m not getting inside my PropertGroup tag.
Why can’t .netstandard just output an executable that could be activated by either coreclr or netfx (like how netfx executables can be activated by either mono or netfx)? If an assembly is targeting .netstandard, that is only to avoid accidentally referencing nonportable APIs during compiletime but shouldn’t affect the emitted image (beyond getting things like default method parameters and constants from a different assembly than if it were targeting corefx or netfx—but that shouldn’t be any more or less of an issue than it is for the portable class libraries which target .netstandard and support both runtimes with one binary assembly).
There are differences in how .net core and netfx/mono resolve native assets (so/dylib/dll) and runtimes. So the most direct need is that the selected target framework triggers build logic to generate runtime artifacts and execute any necessary conflict resolution (e.g. .runtimeconfig.json
/.deps.json
/runtimes/**
for .net core, .exe.config
with binding redirects and copied NuGet dlls for net*)
If you are brave (DO NOT USE THIS IN PRODUCTION!!), you can change your csproj to the following:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>exe</OutputType>
<TargetExt>.exe</TargetExt>
</PropertyGroup>
</Project>
Then copy over a .runtimeconfig.json
(renaming it to match the target) from a working .net core app and a .exe.config
from a working net* app, you should be able to create simple (!) console apps that can run via some.exe
/ dotnet some.exe
/ mono some.exe
, but things could go to hell quickly with any RID-specific or TFM-specific packages ("bait-and-switch" packages or nupkgs containing ).
Relatedly, ASP NET non-core works so long as RunComand
property is defined and a few other things like this:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Library</OutputType>
<OutputPath>bin\</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<RunCommand>$(MSBuildExtensionsPath64)\..\IIS Express\iisexpress</RunCommand>
<RunArguments>/path:"$(MSBuildProjectDirectory)" /port:18082</RunArguments>
</PropertyGroup>
...rest of file...
</Project>
Obviously use whatever port and IIS bitness you want
(Improved thanks to @rainersigwald)
Ideally we'd be able to use
$(ProjectDir)
instead of$(SolutionDir)Your\Project\Folder\Path
, but that comes back empty for me. Let me know if you find a fix for that.
@GrahamTheCoder Are you looking for $(MSBuildProjectDirectory)
? Documentation here.
@rainersigwald Ah yes, that's the one, thanks (I'll update the example for copy and pasting ease)
Ported from https://github.com/dotnet/roslyn-project-system/issues/1309