Benchmarkdotnet: Detect correct version of .NET Core

Created on 14 May 2017  路  16Comments  路  Source: dotnet/BenchmarkDotNet

If we run the current version of BenchmarkDotNet on .NET Core, we will get something like this in summary:

  [Host] : .NET Core 4.6.25211.01, 64bit RyuJIT

.NET Core 4.6.25211.01 is the actual value of System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.
However, it's very confusing because the correct version of .NET Core runtime should be like 1.0.5 or 1.1.2.

enhancement

Most helpful comment

Ok, it seems that we have the solution (thanks Daniel Steiner for the idea):

public static string GetNetCoreVersion()
{
  var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
  var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
  int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
  if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
    return assemblyPath[netCoreAppIndex + 1];
  return null;
}

I checked it on 1.1.2 and 2.0.0-preview1-002111-00; on Windows and Linux. Everything works fine.

However, I suggest to keep the corresponded framework version and print something like this:

.NET Core 1.1.2 (Framework 4.6.25211.01)

Also, instead of

Clr 4.0.30319.42000

it would be better to print something like

.NET Framework 4.7 (CLR 4.0.30319.42000)

See also: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

In this way, we will match target framework versions, show the most important numbers in the first place, and don't skip any details about runtime version.

@adamsitnik, what do you think?

All 16 comments

@adamsitnik, any ideas?

@AndreyAkinshin I don't have any idea for a perfect solution. But when I try to detect if we are running on .NET Core 1.1 or 2.0 I do sth like this:

var assembly = Assembly.Load(new AssemblyName("System.Runtime"));
if (assembly.FullName.Contains("Version=4.1.1"))
       return NetCoreApp11;

so maybe we could use this setting or ask somebody from MS how to get it.

Ok, it seems that we have the solution (thanks Daniel Steiner for the idea):

public static string GetNetCoreVersion()
{
  var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
  var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
  int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
  if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
    return assemblyPath[netCoreAppIndex + 1];
  return null;
}

I checked it on 1.1.2 and 2.0.0-preview1-002111-00; on Windows and Linux. Everything works fine.

However, I suggest to keep the corresponded framework version and print something like this:

.NET Core 1.1.2 (Framework 4.6.25211.01)

Also, instead of

Clr 4.0.30319.42000

it would be better to print something like

.NET Framework 4.7 (CLR 4.0.30319.42000)

See also: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

In this way, we will match target framework versions, show the most important numbers in the first place, and don't skip any details about runtime version.

@adamsitnik, what do you think?

However, I suggest to keep the corresponded framework version and print something like this:

I like this idea! It's much better for the .NET Core to show this well know version id, instead of 4.x.y.z

I have recently added code that detects .NET framework version based on the registry key. We can use this code to detect it. However I am not sure about Mono.

Good to know. Ok., I will do it. A few more questions:

  • Does it make sense to rename Job.Clr to something like Job.Framework. I'm not sure that all of our users understand that Clr refers to the Full .NET Framework.
  • Probably it's also make sense to rename dotnet cli version to .NET Core SDK.

@adamsitnik, what do you think?

Does it make sense to rename Job.Clr to something like Job.Framework. I'm not sure that all of our users understand that Clr refers to the Full .NET Framework.

I think that the people who want to use this feature will know the difference. It's used only when you want to compare two different runtimes. Maybe we can just add a \\\ <summary> comment?

Probably it's also make sense to rename dotnet cli version to .NET Core SDK.

What we display is dotnet cli version numer, so it should not be renamed. However, the dotnet cli is more stable now, so maybe we can even remove it from summary? It was required mostly for troubleshooting dotnet cli problems when every version of dotnet cli was breaking something

I don't think that we should skip it. Also, people usually don't install pure dotnet cli (without runtime), they install .NET Core SDK (which is basically cli + runtime(s)). This information can be also important when we run a new-style csproj project with a netXX target: in this case we don't have any information about .NET Core stuff in the "job" section of the summary.

According to the latest dotnet --help:

位 dotnet -h
.NET Command Line Tools (2.0.0-preview2-006497)
Usage: dotnet [runtime-options] [path-to-application]
Usage: dotnet [command] [arguments] [command-options]

path-to-application:
  The path to an application .dll file to execute.

SDK commands:
  new              Initialize .NET projects.
  restore          Restore dependencies specified in the .NET project.
  run              Compiles and immediately executes a .NET project.
  build            Builds a .NET project.
  publish          Publishes a .NET project for deployment (including the runtime).
  test             Runs unit tests using the test runner specified in the project.
  pack             Creates a NuGet package.
  migrate          Migrates a project.json based project to a msbuild based project.
  clean            Clean build output(s).
  sln              Modify solution (SLN) files.
  add              Add reference to the project.
  remove           Remove reference from the project.
  list             List reference in the project.
  nuget            Provides additional NuGet commands.
  msbuild          Runs Microsoft Build Engine (MSBuild).
  vstest           Runs Microsoft Test Execution Command Line Tool.
  -v|--version     Display .NET Core SDK version.
  -i|--info        Display .NET Core information.
  -d|--diagnostics Enable diagnostic output.

Common options:
  -v|--verbosity        Set the verbosity level of the command. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].
  -h|--help             Show help.

Run 'dotnet COMMAND --help' for more information on a command.

runtime-options:
  --additionalprobingpath <path>    Path containing probing policy and assemblies to probe for.
  --depsfile <path>                 Path to <application>.deps.json file.
  --runtimeconfig <path>            Path to <application>.runtimeconfig.json file.
  --fx-version <version>            Version of the installed Shared Framework to use to run the application.
  --roll-forward-on-no-candidate-fx Roll forward on no candidate shared framework is enabled.
  --additional-deps <path>          Path to additonal deps.json file.

dotnet --version returns the .NET Core SDK version. dotnet cli can operate with different SDK, users can specify the target SDK version in global.json. So, I still want to rename dotnet cli version to .NET Core SDK. @adamsitnik, is it ok to you?

@AndreyAkinshin sure! it turns out that I was wrong

I made some changaes, now the summary has the following form:

.NET Core SDK=1.0.4
  [Host] : .NET Core 1.1.2 (Framework 4.6.25211.01), 64bit RyuJIT
  CLR    : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.2101.1
  Core   : .NET Core 1.1.2 (Framework 4.6.25211.01), 64bit RyuJIT
  Mono   : Mono 5.0.1 (Visual Studio), 64bit 

great!

@AndreyAkinshin Unfortunately GetNetCoreVersion() is not working when used in Ubuntu Docker container images, since the assembly.CodeBase is file:///app/System.Private.CoreLib.dll

Is there a reliable way to get the .NET Core runtime version number at runtime that works in Docker containers as well, please?

Code: RuntimeInformation.FrameworkDescription
Output: .NET Core 4.6.00001.0

Code: typeof(GCSettings).GetTypeInfo().Assembly.CodeBase
Output: file:///app/System.Private.CoreLib.dll

what does the RuntimeInformation.FrameworkDescription returns?

Code: RuntimeInformation.FrameworkDescription
Output: .NET Core 4.6.00001.0

Code: typeof(GCSettings).GetTypeInfo().Assembly.CodeBase
Output: file:///app/System.Private.CoreLib.dll

I created a separate issue for the Docker problem: https://github.com/dotnet/BenchmarkDotNet/issues/788

Same thing happens when running an app published with the --self-contained parameter. I guess that's what's being used when deploying to docker...

Assembly.CodBase points to _System.Private.CoreLib.dll_ dll

Was this page helpful?
0 / 5 - 0 ratings