dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.73k stars 1.07k forks source link

Cannot run dotnet core WinForms app on .Net 6.0 #24503

Open lukos opened 2 years ago

lukos commented 2 years ago

Problem description: Created a new .Net 6.0 winforms app. Built the published content with:

dotnet publish EmailTracker.sln --configuration Release --runtime win10-x64 --no-build --self-contained false

Deployed via CD server onto server and attempted to run the exe. Error message:

image

Click through and download the 6.0.3 desktop runtime. If I run the app again, same error. I tried installing the base .net core runtime too but still the same error.

Error in event log:

Message: A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet\'.

That file does not exist in that folder but it does exist further down under dotnet/shared/Microsoft.NETCore.App/6.0.3 (and other versioned folders)

Then it says Failed to run as a self-contained app, which is fine because it is not supposed to be self-contained.

Expected behavior: I would expect that it would just work when I run the program with the correct runtime installed. Otherwise a much more specific error message if I've done something too stupid because this is show-stopping stuff for a new framework that worked perfectly until I tried to deploy it. Understand all the publish options, the SDK for building and the various project settings is very confusing so I might have got something wrong there.

Minimal repro: This is just an app with a single form and nothing special to deploy but I expect it won't be easy to recreate otherwise you would see it lots of other places.

Deployment server(s): Windows Server 2016 Datacenter 64 bit.

dreddy-work commented 2 years ago

Unfortunately, this is by design. Any application built against .NET 6.0.3+ will be able to run only on machines with .NET 6.0.3+. Please see https://github.com/dotnet/winforms/issues/6663 for more details. If you explicitly install .NET 6.0.3 from here on the machine where you are running this app, it should work.

lukos commented 2 years ago

Sorry why have you closed this? I built this targeting 6.0.3 and I have installed the runtime for 6.0.3 on the target machines, that is the whole reason I raised this issue, I still get an error.

dreddy-work commented 2 years ago

Sorry why have you closed this? I built this targeting 6.0.3 and I have installed the runtime for 6.0.3 on the target machines, that is the whole reason I raised this issue, I still get an error.

Apologize, I misread you were trying to run it on 6.0 but not on 6.0.3. Let us try repro this.

lukos commented 2 years ago

The 6.0 is just what is available in the project target properties i.e. you can choose core 2.2, 2.2, 3.1 5 or 6

Olina-Zhang commented 2 years ago

We cannot repro this issue, after published app with the command "dotnet publish EmailTracker.sln --configuration Release --no-build --self-contained false", on a clean machine, without 6.0.3 installed, a dialog about following downloading pops up. And once we installed it, app can be ran successfully. image

RussKie commented 2 years ago

I am afraid I can't repo the issue either.

  1. created a brand new Windows Forms app
    dotnet new winforms
  2. Publish
    dotnet publish --configuration Release --runtime win10-x64 --self-contained false
  3. Copy to a brand new VM that has no .NET runtime or SDK installed
  4. Run the app, follow the prompt to download the desktop runtime
  5. Install the desktop runtime
  6. Run the app

@lukos were you following the same steps? If this issue specific to a specific workstation or occurs on different workstations?

lukos commented 2 years ago

It fails the same way on a number of deployment targets with the same problem. Did you try on Windows Server 2016? Not sure why it should matter but it might.

The servers also have other dotnet runtimes installed but didn't have desktop 6.0 until I ran the app, used the link and installed the new runtime.

This is a real shame because I have fallen at the first hurdle, and this makes winforms v6.0 unusable for us. There must be a better way to debug why it cannot detect the installed runtime? The complete details from the error logged in the event log are:

Description: A .NET application failed.
Application: EmailTracker.exe
Path: C:\Octopus\Applications\EmailTracker\1.0.0.13\EmailTracker.exe
Message: A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet\'.
Failed to run as a self-contained app.
  - The application was run as a self-contained app because 'C:\Octopus\Applications\EmailTracker\1.0.0.13\EmailTracker.runtimeconfig.json' did not specify a framework.
  - If this should be a framework-dependent app, specify the appropriate framework in 'C:\Octopus\Applications\EmailTracker\1.0.0.13\EmailTracker.runtimeconfig.json'.

But the runtimeconfig.json DOES include 6.0.3:

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "includedFrameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "6.0.3"
      },
      {
        "name": "Microsoft.WindowsDesktop.App",
        "version": "6.0.3"
      }
    ],
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
    }
  }
}

Is it possible that the templates in Visual Studio 2022 are not correct? I shouldn't be having to mess around with config files just to get a .net 6 app working out of the box surely?

lukos commented 2 years ago

image

RussKie commented 2 years ago

@lukos: yes, these workloads look good. On my VM I only installed windowsdesktop-runtime-6.0.3-win-x64.exe, which installed the following: image image image

I have hostpolicy.dll located in C:\Program Files\dotnet\x64\shared\Microsoft.NETCore.App\6.0.3.

WinFormsApp2.runtimeconfig.json ```json { "runtimeOptions": { "tfm": "net6.0", "frameworks": [ { "name": "Microsoft.NETCore.App", "version": "6.0.3" }, { "name": "Microsoft.WindowsDesktop.App", "version": "6.0.3" } ], "configProperties": { "System.Reflection.Metadata.MetadataUpdater.IsSupported": false } } } ```
WinFormsApp2.deps.json ```json { "runtimeTarget": { "name": ".NETCoreApp,Version=v6.0/win10-x64", "signature": "" }, "compilationOptions": {}, "targets": { ".NETCoreApp,Version=v6.0": {}, ".NETCoreApp,Version=v6.0/win10-x64": { "WinFormsApp2/1.0.0": { "runtime": { "WinFormsApp2.dll": {} } } } }, "libraries": { "WinFormsApp2/1.0.0": { "type": "project", "serviceable": false, "sha512": "" } } } ```

We've tested Windows Server 2019 and found no issues. We'll see if we can provision a Windows Server 2016 VM to test.

@dsplaisted do you have any thoughts on dotnet/sdk#24503?

Olina-Zhang commented 2 years ago

Tested it on Windows server 2016, after installed .Net 6.0.3, the published app can be launched successfully: image

lukos commented 2 years ago

@Olina-Zhang Did you test this with the same build parameters for dotnet publish? I am trying to work out what other difference there could be and why this is not working on our servers.

Olina-Zhang commented 2 years ago

@lukos I just removed --runtime win10-x64 from command dotnet publish EmailTracker.sln --configuration Release --runtime win10-x64 --no-build --self-contained false because I can't use it publish app successfully.

lukos commented 2 years ago

Thanks @Olina-Zhang I've just found out what wasn't working.

I was passing --no-build to dotnet publish because we have already run dotnet build and run automated tests so it seemed pointless to build it again as part of publish. I removed that flag and now it works.

I'm not sure if that is strictly a bug but is definitely a gotcha (I have 20 years .Net programming so I'm not a noob) but not sure how this could work differently because in other places (not Winforms) we do it this way and it's fine. Maybe --self-contained false should override no-build or something?

RussKie commented 2 years ago

@lukos great to hear you found the root cause.

I was passing --no-build to dotnet publish because we have already run dotnet build and run automated tests so it seemed pointless to build it again as part of publish. I removed that flag and now it works.

I'm not sure if that is strictly a bug but is definitely a gotcha (I have 20 years .Net programming so I'm not a noob) but not sure how this could work differently because in other places (not Winforms) we do it this way and it's fine. Maybe --self-contained false should override no-build or something?

Moving the issue to the SDK as this may be something the SDK needs to fix or (better) document.

RussKie commented 2 years ago

Thank you @Olina-Zhang.

AraHaan commented 2 years ago

I have discovered that the logic that generates the runtimeconfig.json does not ensure that the Microsoft.NETCore.App was listed last and so it was looking for it in Microsoft.AspNetCore.App for me.

I ran into this on a exe project that references 3 frameworks though.