dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.15k stars 4.71k forks source link

AppContext.TargetFrameworkName differs between CoreRT and CoreCLR #23101

Closed danmoseley closed 4 years ago

danmoseley commented 7 years ago

https://github.com/dotnet/coreclr/pull/13266#pullrequestreview-55061899

In CoreCLR, AppContext.TargetFrameworkName will always return null. On CoreRT/ProjectN, it will return attribute value from main exe https://github.com/dotnet/corert/blob/ff7eba504516fa0bc0a50357ad559c19b45d1d51/src/System.Private.CoreLib/src/System/AppContext.cs#L45

If we are OK with updating CoreCLR, we return return Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName; from AppDomainSetup.TargetFrameworkName

this will cause AppContext to parse ".NETCoreApp,Version=v2.0" and have an identifier and version instead of empty/null as it currently has and I don't know what that will do downstream.

danmoseley commented 7 years ago

@AlexGhiondea is this a type you have context on? It's the Core equivalent of Quirking? Should we take this change?

clairernovotny commented 7 years ago

This would be very useful, as there's no current reliable way at runtime to get the currently executing framework and version.

Created a new issue for this https://github.com/dotnet/corefx/issues/23197

AlexGhiondea commented 7 years ago

@danmosemsft the AppContext type is primarily used for quirking but has also a few other uses.

On CoreCLR we don't return null. We actually look at AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName.

On CoreCLR I am not sure we want to read the value from the main exe as a) there might not be an entry assembly and b) the host can choose to put a different TFM on the default AppDomain.

/cc @jkotas

jkotas commented 6 years ago

We should return value from the TargetFrameworkName attribute in CoreCLR, I think. It is one line change - copy the implementation from CoreRT:

        public static string TargetFrameworkName => Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
Anipik commented 6 years ago

@jkotas I tried this change. But still the value being returned in the Corefx Tests is null. Currently Debugging to get more info

danmoseley commented 6 years ago

This is because xunit.console.netcore.exe is the entrypoint assembly for your test and it is missing the attribute. I assume it does work when you do "dotnet.exe myapp.dll" as myapp.dll is the entrypoint assembly and should have it. For testing purposes I would either update the xunit exe's or better still use RemoteInvoke(), adding the TargetFrameworkAttribute manually into https://github.com/dotnet/corefx/blob/master/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/AssemblyAttributes.cs if you need to