Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AppHost] Don’t assume that last framework in runtimeconfig list contains hostpolicy.dll #71027

Open
AraHaan opened this issue Jun 20, 2022 · 19 comments
Milestone

Comments

@AraHaan
Copy link
Member

AraHaan commented Jun 20, 2022

Description

Currently it seems that the apphost looks for hostpolicy in the last framework that is in runtimeconfig which is not true, instead it should hard code it to look in the Microsoft.NETCore.App framework regardless of how many frameworks are in the runtimeconfig.json file.

Reproduction Steps

Have an application that generates an runtimeconfig where Microsoft.NETCore.App does not appear last (in my case the problem happens when aspnetcore is last so it looks in the aspnetcore framework).

Expected behavior

For the AppHost to either ignore runtimeconfig when looking for hostpolicy by hard coding it or for the .NET SDK to always output it last regardless of how many frameworks the application depends on.

Actual behavior

The apphost always looks for the hostpolicy assembly in the framework listed last in runtimeconfig.

Regression?

Not sure.

Known Workarounds

Currently the only option is to manually patch the runtimeconfig to reorder the frameworks listed after building.

Configuration

The code is running on 6.0.6 of the .NET SDK Frameworks.

Windows 11 21H2.
Arch: x64 (AMD64)
Specifc to config?: I do not think so, other than sdk generated runtimeconfig.json which cannot be bypassed to use a premade runtimeconfig that is manually maintained in the mean time.
Not using blazor at all.

Other information

I think the problem lies in the apphost or whatever it is that tries to load hostpolicy.dll. As for the spot in code, I cant point to where the exact line it is failing at as I am not sure myself.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jun 20, 2022
@ghost
Copy link

ghost commented Jun 20, 2022

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Currently it seems that the apphost looks for hostpolicy in the last framework that is in runtimeconfig which is not true, instead it should hard code it to look in the Microsoft.NETCore.App framework regardless of how many frameworks are in the runtimeconfig.json file.

Reproduction Steps

Have an application that generates an runtimeconfig where Microsoft.NETCore.App does not appear last (in my case the problem happens when aspnetcore is last so it looks in the aspnetcore framework).

Expected behavior

For the AppHost to either ignore runtimeconfig when looking for hostpolicy by hard coding it or for the .NET SDK to always output it last regardless of how many frameworks the application depends on.

Actual behavior

The apphost always looks for the hostpolicy assembly in the framework listed last in runtimeconfig.

Regression?

Not sure.

Known Workarounds

Currently the only option is to manually patch the runtimeconfig to reorder the frameworks listed after building.

Configuration

The code is running on 6.0.6 of the .NET SDK Frameworks.

Windows 11 21H2.
Arch: x64 (AMD64)
Specifc to config?: I do not think so, other than sdk generated runtimeconfig.json which cannot be bypassed to use a premade runtimeconfig that is manually maintained in the mean time.
Not using blazor at all.

Other information

I think the problem lies in the apphost or whatever it is that tries to load hostpolicy.dll. As for the spot in code, I cant point to where the exact line it is failing at as I am not sure myself.

Author: AraHaan
Assignees: -
Labels:

area-Host

Milestone: -

@AraHaan
Copy link
Member Author

AraHaan commented Jun 20, 2022

Oh yeah, forgot to mention this happens in FDD deployments and the code does not have to be published to trigger it.

@AraHaan
Copy link
Member Author

AraHaan commented Jun 21, 2022

return *fx_definitions[fx_definitions.size() - 1];

What I think it should be changed to:

    for (auto& fx_definition : fx_definitions)
    {
        if (fx_definition->get_name() != "Microsoft.NETCore.App")
        {
            continue;
        }

        return *fx_definition;
    }

    // not found? Return null.
    return nullptr;

@vitek-karas
Copy link
Member

@AraHaan do you have a repro for this?

I tried locally with an ASP.NET app and it produces a runtimeconfig.json like this by default:

    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "7.0.0-preview.5.22301.12"
      },
      {
        "name": "Microsoft.AspNetCore.App",
        "version": "7.0.0-preview.5.22303.8"
      }
    ],

Running the app works just fine, looking at the host trace it shows that the host correctly ordered the frameworks:

--- Summary of all frameworks:
     framework:'Microsoft.AspNetCore.App', lowest requested version='7.0.0-preview.5.22303.8', found version='7.0.0-preview.5.22303.8', effective reference version='7.0.0-preview.5.22303.8' apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, folder=C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\7.0.0-preview.5.22303.8
     framework:'Microsoft.NETCore.App', lowest requested version='7.0.0-preview.5.22301.12', found version='7.0.0-preview.5.22301.12', effective reference version='7.0.0-preview.5.22301.12' apply_patches=1, version_compatibility_range=patch, roll_to_highest_version=0, folder=C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.0-preview.5.22301.12

And that it correctly looked for hostpolicy in the lowest level framework (NETCore.App):

--- Resolving hostpolicy.dll version from deps json [C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.0-preview.5.22301.12\Microsoft.NETCore.App.deps.json]

The code you're referring to relies on couple of assumptions:

  • There's a single lowest level framework - the "Root" - currently this is always the Microsoft.NETCore.App
  • When the host resolves frameworks it orders them in the fx_definitions array from highest to lowest level - the first is always the app (highest) and the last is always the "root" (lowest)

The ordering is done in the fx_resolver, and while a bit complex I guess this line is a good place to point to:

std::rotate(existing_framework, existing_framework + 1, fx_definitions.end());

@AraHaan
Copy link
Member Author

AraHaan commented Jun 21, 2022

It probably happens because I also use a framework that depends on Microsoft.NETCore.App and Microsoft.AspNetCore.App causing it to look for hostpolicy in aspnetcore.

I have pushed what I did to generate the frameworks which my application that fails uses to github:

After that in the new project, make sure it has it's own nuget.config to use for packages have the above directories in it's "feeds". Then add these to the project (after running the generated installers for the bitness of the .NET SDK that is the default):

  <Sdk Name="Serilog.Sdk" Version="6.0.6" />
  <Sdk Name="Microsoft.EntityFrameworkCore.Sdk" Version="6.0.6" />

The reason why I try it this was is due to dotnet store not working for .NET 6+ and I needed a way to share the dependencies between framework dependent applications without having them copied to their output directories so making them into their own shared frameworks was the best option for me.

However in my case the application targets .NET 6 and so all of it's frameworks are using the 6.0.6 servicing of the default frameworks.

@vitek-karas
Copy link
Member

Sorry it took me so long...
Can you please share the runtimeconfig.json for the app and the custom frameworks?

Or even better, can you please grab a host trace when it fails? https://github.com/dotnet/runtime/blob/main/docs/design/features/host-tracing.md#trace-routing
(Please note that the host trace contains information about the machine and user, so make sure you're OK to share it publicly)

@vitek-karas
Copy link
Member

I was trying to build it locally but it fails to find matching Microsoft.DotNet.Build.Tasks.Installers package. I must admit I don't understand what the project is trying to do, but it apparently relies on some internal package.

@AraHaan
Copy link
Member Author

AraHaan commented Jul 8, 2022

That failure was due to the fact I did not pin a specific version of that installers package and so a tool in it would fail to run because it expects 7.0.0 of the runtime (which does not exist in the stable state currently).

I think I should have pushed an commit to all of those repos that pins it to the last known version that will run with the 6.0.0 runtime.

Edit: It seems I forgot to push that update for the Serilog installers repo I linked above.

@AraHaan
Copy link
Member Author

AraHaan commented Jul 8, 2022

Alright pushed update to the Serilog installers, try to git pull. Also version changed on it as well.

@vitek-karas
Copy link
Member

I think the EF repo is still broken...

@AraHaan
Copy link
Member Author

AraHaan commented Jul 9, 2022

You are right, I forgot to commit to it as well (or push).

@AraHaan
Copy link
Member Author

AraHaan commented Jul 9, 2022

@vitek-karas ok, pushed.

@agocke agocke added this to the Future milestone Jul 11, 2022
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jul 11, 2022
@vitek-karas
Copy link
Member

Thanks a lot for your help, I was able to repro this.
I created #71959 as the in-house repro within our test framework.

Workaround is to change the order of framework dependencies in the two frameworks you create - make it put NETCore.App last (not sure if SDK can do that, maybe you would need to add a post-build step to edit the json).

AraHaan added a commit to Elskom/EFCore-Installer that referenced this issue Jul 12, 2022
AraHaan added a commit to Elskom/Serilog-Installer that referenced this issue Jul 12, 2022
AraHaan added a commit to Elskom/Remora.Discord-Installer that referenced this issue Jul 12, 2022
@AraHaan
Copy link
Member Author

AraHaan commented Jul 12, 2022

Ok, I tried the workaround and it seems to not have worked.

This time when I did:

Into any project (which will reference the AspNetCore framework if it is not referenced) then when I try to run it it will look for the hostpolicy in the AspNetCore framework still for some reason.

runtimeconfig file
{
  "runtimeOptions": {
    "tfm": "net6.0",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "6.0.0"
      },
      {
        "name": "Microsoft.AspNetCore.App",
        "version": "6.0.0"
      },
      {
        "name": "Microsoft.EntityFrameworkCore.App",
        "version": "6.0.6"
      },
      {
        "name": "Remora.Discord.App",
        "version": "2022.43.0"
      },
      {
        "name": "Serilog.App",
        "version": "6.0.6"
      }
    ],
    "configProperties": {
      "System.GC.Server": true,
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
      "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
    }
  }
}
trace log
Tracing enabled @ Tue Jul 12 05:12:01 2022 GMT
--- Invoked apphost [version: 6.0.5, commit hash: 70ae3df4a6f3c92fb6b315afc405edd10ff38579] main = {
H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.exe
}
Redirecting errors to custom writer.
The managed DLL bound to this executable is: 'MyBot.dll'
Using global installation location [C:\Program Files\dotnet\] as runtime location.
Reading fx resolver directory=[C:\Program Files\dotnet\host\fxr]
Considering fxr version=[3.1.26]...
Considering fxr version=[5.0.17]...
Considering fxr version=[6.0.0]...
Considering fxr version=[6.0.1]...
Considering fxr version=[6.0.2]...
Considering fxr version=[6.0.5]...
Considering fxr version=[6.0.6]...
Detected latest fxr version=[C:\Program Files\dotnet\host\fxr\6.0.6]...
Resolved fxr [C:\Program Files\dotnet\host\fxr\6.0.6\hostfxr.dll]...
Loaded library from C:\Program Files\dotnet\host\fxr\6.0.6\hostfxr.dll
Invoking fx resolver [C:\Program Files\dotnet\host\fxr\6.0.6\hostfxr.dll] hostfxr_main_startupinfo
Host path: [H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.exe]
Dotnet path: [C:\Program Files\dotnet\]
App path: [H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.dll]
Tracing enabled @ Tue Jul 12 05:12:01 2022 GMT
--- Invoked hostfxr_main_startupinfo [commit hash: 7cca709db2944a09b4db6ca7b20c457ff260fb5a]
Checking if CoreCLR path exists=[C:\Program Files\dotnet\coreclr.dll]
--- Executing in a native executable mode...
Using dotnet root path [C:\Program Files\dotnet\]
App runtimeconfig.json from [H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.dll]
Runtime config is cfg=H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.runtimeconfig.json dev=H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.runtimeconfig.dev.json
Attempting to read runtime config: H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.runtimeconfig.json
Attempting to read dev runtime config: H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.runtimeconfig.dev.json
Runtime config [H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.NETCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.0'.
--- Resolving FX directory, name 'Microsoft.NETCore.App' version '6.0.0'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\dotnet]
Attempting FX roll forward starting from version='[6.0.0]', apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release greater than or equal version to [6.0.0]
Found version [6.0.6]
Applying patch roll forward from [6.0.6] on release only
Inspecting version... [6.0.6]
Changing Selected FX version from [] to [C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6]
Chose FX version [C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6]
Runtime config is cfg=C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.json dev=C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.dev.json
Attempting to read runtime config: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.json
Attempting to read dev runtime config: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.dev.json
Runtime config [C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.AspNetCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.0'.
--- Resolving FX directory, name 'Microsoft.AspNetCore.App' version '6.0.0'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\dotnet]
Attempting FX roll forward starting from version='[6.0.0]', apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release greater than or equal version to [6.0.0]
Found version [6.0.6]
Applying patch roll forward from [6.0.6] on release only
Inspecting version... [6.0.6]
Changing Selected FX version from [] to [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6]
Chose FX version [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6]
Runtime config is cfg=C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.json dev=C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.dev.json
Attempting to read runtime config: C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.json
Attempting to read dev runtime config: C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.dev.json
Runtime config [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.NETCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.6'.
--- Restarting all framework resolution because the previously resolved framework 'Microsoft.NETCore.App', version '6.0.0' must be re-resolved with the new version '6.0.6', apply_patches=1, version_compatibility_range=patch, roll_to_highest_version=0 .
--- The specified framework 'Microsoft.NETCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.6'.
--- Resolving FX directory, name 'Microsoft.NETCore.App' version '6.0.6'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\dotnet]
Attempting FX roll forward starting from version='[6.0.6]', apply_patches=1, version_compatibility_range=patch, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [patch]. Looking for the lowest release greater than or equal version to [6.0.6]
Found version [6.0.6]
Applying patch roll forward from [6.0.6] on release only
Inspecting version... [6.0.6]
Changing Selected FX version from [] to [C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6]
Chose FX version [C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6]
Runtime config is cfg=C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.json dev=C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.dev.json
Attempting to read runtime config: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.json
Attempting to read dev runtime config: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.dev.json
Runtime config [C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6\Microsoft.NETCore.App.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.AspNetCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.0'.
--- Resolving FX directory, name 'Microsoft.AspNetCore.App' version '6.0.0'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\dotnet]
Attempting FX roll forward starting from version='[6.0.0]', apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release greater than or equal version to [6.0.0]
Found version [6.0.6]
Applying patch roll forward from [6.0.6] on release only
Inspecting version... [6.0.6]
Changing Selected FX version from [] to [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6]
Chose FX version [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6]
Runtime config is cfg=C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.json dev=C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.dev.json
Attempting to read runtime config: C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.json
Attempting to read dev runtime config: C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.dev.json
Runtime config [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.NETCore.App', version '6.0.6', apply_patches=1, version_compatibility_range=patch is compatible with the previously referenced version '6.0.6'.
--- The specified framework 'Microsoft.EntityFrameworkCore.App', version '6.0.6', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.6'.
--- Resolving FX directory, name 'Microsoft.EntityFrameworkCore.App' version '6.0.6'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\dotnet]
Attempting FX roll forward starting from version='[6.0.6]', apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release greater than or equal version to [6.0.6]
Found version [6.0.6]
Applying patch roll forward from [6.0.6] on release only
Inspecting version... [6.0.6]
Changing Selected FX version from [] to [C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6]
Chose FX version [C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6]
Runtime config is cfg=C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6\Microsoft.EntityFrameworkCore.App.runtimeconfig.json dev=C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6\Microsoft.EntityFrameworkCore.App.runtimeconfig.dev.json
Attempting to read runtime config: C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6\Microsoft.EntityFrameworkCore.App.runtimeconfig.json
Attempting to read dev runtime config: C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6\Microsoft.EntityFrameworkCore.App.runtimeconfig.dev.json
Runtime config [C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6\Microsoft.EntityFrameworkCore.App.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.NETCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.6'.
--- The specified framework 'Microsoft.AspNetCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.0'.
--- The specified framework 'Remora.Discord.App', version '2022.43.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '2022.43.0'.
--- Resolving FX directory, name 'Remora.Discord.App' version '2022.43.0'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\dotnet]
Attempting FX roll forward starting from version='[2022.43.0]', apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release greater than or equal version to [2022.43.0]
Found version [2022.43.0]
Applying patch roll forward from [2022.43.0] on release only
Inspecting version... [2022.43.0]
Changing Selected FX version from [] to [C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0]
Chose FX version [C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0]
Runtime config is cfg=C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0\Remora.Discord.App.runtimeconfig.json dev=C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0\Remora.Discord.App.runtimeconfig.dev.json
Attempting to read runtime config: C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0\Remora.Discord.App.runtimeconfig.json
Attempting to read dev runtime config: C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0\Remora.Discord.App.runtimeconfig.dev.json
Runtime config [C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0\Remora.Discord.App.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.NETCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.6'.
--- The specified framework 'Microsoft.AspNetCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.0'.
--- The specified framework 'Serilog.App', version '6.0.6', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.6'.
--- Resolving FX directory, name 'Serilog.App' version '6.0.6'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\dotnet]
Attempting FX roll forward starting from version='[6.0.6]', apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release greater than or equal version to [6.0.6]
Found version [6.0.6]
Applying patch roll forward from [6.0.6] on release only
Inspecting version... [6.0.6]
Changing Selected FX version from [] to [C:\Program Files\dotnet\shared\Serilog.App\6.0.6]
Chose FX version [C:\Program Files\dotnet\shared\Serilog.App\6.0.6]
Runtime config is cfg=C:\Program Files\dotnet\shared\Serilog.App\6.0.6\Serilog.App.runtimeconfig.json dev=C:\Program Files\dotnet\shared\Serilog.App\6.0.6\Serilog.App.runtimeconfig.dev.json
Attempting to read runtime config: C:\Program Files\dotnet\shared\Serilog.App\6.0.6\Serilog.App.runtimeconfig.json
Attempting to read dev runtime config: C:\Program Files\dotnet\shared\Serilog.App\6.0.6\Serilog.App.runtimeconfig.dev.json
Runtime config [C:\Program Files\dotnet\shared\Serilog.App\6.0.6\Serilog.App.runtimeconfig.json] is valid=[1]
--- The specified framework 'Microsoft.NETCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.6'.
--- The specified framework 'Microsoft.AspNetCore.App', version '6.0.0', apply_patches=1, version_compatibility_range=minor is compatible with the previously referenced version '6.0.0'.
--- Summary of all frameworks:
     framework:'Microsoft.EntityFrameworkCore.App', lowest requested version='6.0.6', found version='6.0.6', effective reference version='6.0.6' apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, folder=C:\Program Files\dotnet\shared\Microsoft.EntityFrameworkCore.App\6.0.6
     framework:'Remora.Discord.App', lowest requested version='2022.43.0', found version='2022.43.0', effective reference version='2022.43.0' apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, folder=C:\Program Files\dotnet\shared\Remora.Discord.App\2022.43.0
     framework:'Serilog.App', lowest requested version='6.0.6', found version='6.0.6', effective reference version='6.0.6' apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, folder=C:\Program Files\dotnet\shared\Serilog.App\6.0.6
     framework:'Microsoft.NETCore.App', lowest requested version='6.0.0', found version='6.0.6', effective reference version='6.0.6' apply_patches=1, version_compatibility_range=patch, roll_to_highest_version=0, folder=C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.6
     framework:'Microsoft.AspNetCore.App', lowest requested version='6.0.0', found version='6.0.6', effective reference version='6.0.0' apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, folder=C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6
Executing as a framework-dependent app as per config file [H:\Desktop\github\MyBot\bin\Release\net6.0\MyBot.runtimeconfig.json]
--- Resolving hostpolicy.dll version from deps json [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.deps.json]
Resolved version  from dependency manifest file [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.deps.json]
Dependency manifest C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6\Microsoft.AspNetCore.App.deps.json does not contain an entry for runtime.win-x64.Microsoft.NETCore.DotNetHostPolicy
The expected hostpolicy.dll directory is [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6]
The hostpolicy.dll was not found in [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6]
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6'.
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.6'.

@vitek-karas
Copy link
Member

The workaround is in the SDKs - so in your case for example Serilog.App. It's runtimeconfig needs to list the Microsoft.NETCore.App as the last dependency (and all of the others need to do that as well). I tried this locally with the original repro and it "Fixed" it.

@AraHaan
Copy link
Member Author

AraHaan commented Jul 12, 2022

Perhaps my attempt to workaround it was not matching what you did. Mind if I can see what you did different to fix it?

@AraHaan
Copy link
Member Author

AraHaan commented Jul 13, 2022

I have just now tested a locally built hostfxr with these changes with success to my application that I could not fix locally with this code change:

image

Looks like get_root_framework was another option that can fix it ironically.

AraHaan added a commit to AraHaan/runtime that referenced this issue Jul 13, 2022
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 13, 2022
@vitek-karas
Copy link
Member

Regarding the workaround: I changed the Microsoft.EntityFrameworkCore.App.runtimeconfig.json (the one which is installed into Program Files by your installers) to look like this:

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "frameworks": [
      {
        "name": "Microsoft.AspNetCore.App",
        "version": "6.0.0"
      },
      {
        "name": "Microsoft.NETCore.App",
        "version": "6.0.0"
      }
    ],
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
      "System.Reflection.NullabilityInfoContext.IsSupported": true
    }
  }
}

So moving the Microsoft.NETCore.App reference as last.
I changed the Serilog.App the same way.

With these the app launches without any issues.

Side note: If you're planning to expose these installers publicly I would recommend you rename the frameworks. Currently they look like official Microsoft or Serilog installers which is at least "misleading".

@AraHaan
Copy link
Member Author

AraHaan commented Jul 18, 2022

Workaround is to change the order of framework dependencies in the two frameworks you create - make it put NETCore.App last (not sure if SDK can do that, maybe you would need to add a post-build step to edit the json).

Alright I found a way to have the installers for the frameworks to include the patched runtimeconfig files by:

  • Having the sfxproj file that builds the runtime pack manually import Sdk.props and Sdk.targets from Microsoft.NET.Sdk.
  • After importing Sdk.targets override GenerateBuildRuntimeConfigurationFiles that basically copies a manually maintained runtimeconfig.json file:
  <!-- override the version specified in Microsoft.NET.Sdk.targets -->
  <!-- Work around https://github.com/dotnet/runtime/issues/71027 by adding NETCore.App last in the runtimeconfig file. -->
  <!--
      There is a problem with the automatically generated runtimeconfig.json
      files where it is possible that it can cause the apphost to look for hostpolicy
      in the wrong framework directory.

      As such we must provide our own runtimeconfig file that gets copied to the
      output directory that is manually maintained.
  -->
  <!-- Caution: Dangerous Hack. -->
  <Target
    Name="GenerateBuildRuntimeConfigurationFiles"
    Condition="'$(GenerateRuntimeConfigurationFiles)' == 'true'"
    BeforeTargets="CopyFilesToOutputDirectory">
    <Copy
      SourceFiles="$(MSBuildThisFileDirectory)runtimeconfig.json"
      SkipUnchangedFiles="true"
      DestinationFiles="$(ProjectRuntimeConfigFilePath)" />
    <!--
        For some reason copy creates 2 files instead of just the
        copied file with the new name above.
    -->
    <Delete Files="$(IntermediateOutputPath)runtimeconfig.json" />
  </Target>

I consider this to be dangerous as it is possible for one to forget to update it manually.

Side note: If you're planning to expose these installers publicly I would recommend you rename the frameworks. Currently they look like official Microsoft or Serilog installers which is at least "misleading".

Yeah, those names of the frameworks was to demonstrate the issue.

AraHaan added a commit to Elskom/EFCore-Installer that referenced this issue Jul 18, 2022
The generated ones can result in the consuming application to not be able to load due to hostfxr reordering the frameworks in a way that will cause it to look for hostpolicy in the wrong framework.

Signed-off-by: AraHaan <[email protected]>
AraHaan added a commit to Elskom/EFCore-Installer that referenced this issue Jul 18, 2022
The generated ones can result in the consuming application to not be able to load due to hostfxr reordering the frameworks in a way that will cause it to look for hostpolicy in the wrong framework.

Signed-off-by: AraHaan <[email protected]>
AraHaan added a commit to Elskom/Serilog-Installer that referenced this issue Jul 18, 2022
The generated ones can result in the consuming application to not be able to load due to hostfxr reordering the frameworks in a way that will cause it to look for hostpolicy in the wrong framework.

Signed-off-by: AraHaan <[email protected]>
AraHaan added a commit to Elskom/Serilog-Installer that referenced this issue Jul 18, 2022
…#2)

The generated ones can result in the consuming application to not be able to load due to hostfxr reordering the frameworks in a way that will cause it to look for hostpolicy in the wrong framework.

Signed-off-by: AraHaan <[email protected]>
AraHaan added a commit to Elskom/Remora.Discord-Installer that referenced this issue Jul 18, 2022
The generated ones can result in the consuming application to not be able to load due to hostfxr reordering the frameworks in a way that will cause it to look for hostpolicy in the wrong framework.

Signed-off-by: AraHaan <[email protected]>
AraHaan added a commit to Elskom/Remora.Discord-Installer that referenced this issue Jul 18, 2022
…#2)

The generated ones can result in the consuming application to not be able to load due to hostfxr reordering the frameworks in a way that will cause it to look for hostpolicy in the wrong framework.

Signed-off-by: AraHaan <[email protected]>
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Sep 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

Successfully merging a pull request may close this issue.

3 participants