Home

Why does a LinqPad script targeting .NET 7 identify as .NET Core 3.1?

In Linqpad 7.7.15 (x64), when I run a script that dumps AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName it prints .NETCoreApp,Version=v3.1 - but a new console project in VS targeting .NET 7 prints .NETCoreApp,Version=v7.0

I understand this can vary based on the TargetFrameworkAttribute on an entrypoint assembly - but LinqPad7.exe isn't a .NET assembly (I assume it has some custom CLR startup logic?) but even so, Linqpad runs user-queries in a separate process that I assume would always have the correct assembly attributes that match the selected .NET version in the toolbar.

What's also interesting is that despite having .NET Framework 4.8.1 installed, LinqPad 5 reports it's .NETFramework, Version = v4.6 - and on a Windows Server 2012 R2 machine I have (also with .NET 4.8.1 installed), LinqPad 4 reports .NETFramework,Version=v4.0

...and LinqPad 4 and 5 seem to be having issues with System.Net.ServicePointManager.SecurityProtocol, perhaps for a related reason?

Comments

  • The value that this function returns is based on the TargetFrameworkAttribute of the entry assembly, which is LINQPad7.Query.dll in the case of LINQPad 7. This assembly has been built to target the lowest .NET version that LINQPad 7 supports, which is .NET Core 3.1.

    To get the framework that your query targets, you must query the TargetFrameworkAttribute of the query assembly:

    Assembly.GetExecutingAssembly().GetCustomAttribute<System.Runtime.Versioning.TargetFrameworkAttribute>()?.FrameworkName
    

    Alternatively, query the executing CLR version:

    Environment.Version
    

    Note that with .NET Framework, the CLR version is not the same as the framework version, so this won't help. Instead, you must query the AssemblyInformationalVersionAttribute attribute on a runtime assembly:

    ((AssemblyInformationalVersionAttribute)typeof (object).Assembly.GetCustomAttributes (typeof (AssemblyInformationalVersionAttribute), true)[0]).InformationalVersion
    
  • edited October 2023

    Thanks - but what about ServicePointManager..SecurityProtocol? That property doesn't seem to behave the way MS' documentation suggests (i.e. it never returns SystemDefault in any version of LinqPad I have on any of my computers/VMs).

  • My bad - LINQPad applies the following defaults in LINQPad 5:

    ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
    ServicePointManager.DefaultConnectionLimit = 10;
    

    and in LINQPad 7:

    ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
    ServicePointManager.DefaultConnectionLimit = 10;
    

    This is a kind-of a bug - it should not make any changes to these settings in the query processes. This is a legacy from when the host shared a process with the queries in much earlier versions of LINQPad. I will fix this in LINQPad 8. I can't really change this in LINQPad 5 or 7 because it would be a breaking change.

Sign In or Register to comment.