sdk: Attempting to run a NetStandard class library that's been turned into a console app shows an error about "RunCommand" missing

Ported from https://github.com/dotnet/roslyn-project-system/issues/1309

  1. Create a new C# .NetStandard library.
  2. Open properties pages and change the Application type to Console Application.
  3. Add a static Main method to the class.
  4. F5
---------------------------
Microsoft Visual Studio
---------------------------
Unable to run your project. The "RunCommand" property is not defined.
---------------------------
OK   
---------------------------

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 12
  • Comments: 21 (11 by maintainers)

Commits related to this issue

Most upvoted comments

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:&quot;$(MSBuildProjectDirectory)&quot; /port:18082</RunArguments>
  </PropertyGroup>
  ...rest of file...
</Project>

Obviously use whatever port and IIS bitness you want

(Improved thanks to @rainersigwald)

Any news on this? How can we go around it?

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 ).

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

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?

Maybe we should just give a better error message here?

@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?

@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.

What does running on netstandard mean though? What CLR will it use to run?