dotnet / winforms

Windows Forms is a .NET UI framework for building Windows desktop applications.
MIT License
4.44k stars 988 forks source link

6.0.2 SDK update has broken WinForms apps #6663

Closed EatonZ closed 2 years ago

EatonZ commented 2 years ago

ℹ️ UPDATE: Workaround here for those who need it.

. . .

There appears to be a critical problem with the new 6.0.2 update which makes apps compiled with it fail to start on machines running 6.0.1.

To reproduce, do the following:

  1. Visit Windows Update to update the runtime on your dev machine, and also update Visual Studio 2022 using Visual Studio Installer.
  2. On a client/test machine, install the 6.0.1 desktop runtime. Direct Link
  3. On your dev machine, create a new WinForms project, build it and copy the executable files to the client/test machine.
  4. Run it and it will not start. Event logs show the following:
    Application: WinFormsApp1.exe
    CoreCLR Version: 6.0.121.56705
    .NET Version: 6.0.1
    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.IO.FileLoadException: Could not load file or assembly 'System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
    File name: 'System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
    at WinFormsApp1.Program.Main()

This problem did not happen on .NET 5. I was under the impression patch versions are generally compatible with each other, and I use <RollForward>LatestPatch</RollForward> in my real app, but even with that setting it still crashes.

This is a blocking issue for me because if I distribute an update for my app built on 6.0.2 and the client is still running 6.0.1, that will be bad if the app suddenly stops working.

dreddy-work commented 2 years ago

@RussKie , is this because we are shipping refs with each servicing release now?

RussKie commented 2 years ago

@dreddy-work we do not ship the SDKs in servicing releases, we ship the ref packs.

@EatonZ you're building an app on a higher version of .NET and trying to execute on a lower version. How do you configure SDKs in global.json?

EatonZ commented 2 years ago

@RussKie I don't have anything custom for global.json, but my runtimeconfig.json comes out to be this:

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "rollForward": "LatestPatch",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "6.0.0"
      },
      {
        "name": "Microsoft.WindowsDesktop.App",
        "version": "6.0.0"
      }
    ],
    "configProperties": {
      "System.Diagnostics.Debugger.IsSupported": false,
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
    }
  }
}

To be clear, compiling on a new SDK and running on an older runtime has always worked for me, and my customers.

RussKie commented 2 years ago

@EatonZ it is indeed a major issue with the 6.0.2 servicing release. The assembly versions have been revved from 6.0.0 to 6.0.2, which is causing the issue you're facing. The team is currently discussing different ways this issue may be addressed and ways we can minimise the drama for developers like yourself. Unfortunately there's no easy way out here. In mean time please build your applications against 6.0.0 or 6.0.1.

EatonZ commented 2 years ago

@RussKie Thank you for confirming.

I am fine with going back to building with 6.0.1 again. What is the correct procedure to do that now in a fully updated Visual Studio? It automatically replaced the old SDK with the latest, so what's the process in downgrading without breaking things?

RussKie commented 2 years ago

I believe you can install 6.0.1 from https://dotnet.microsoft.com/en-us/download/dotnet/6.0. In the global.json you can pin the SDK to 6.0.1

{
  "sdk": {
    "version": "6.0.101",
    "rollForward": "disable"
  }
}
EatonZ commented 2 years ago

@RussKie Thank you, everything is back in a working state for me now. It seems like the best way to fix would be to put out a new update that doesn't bump the versions / resets back to 6.0.0.0. Hopefully you can do that soon to avoid a lot of people compiling incompatible software on this version.

Full workaround steps for others who may need help:

  1. Make sure Windows and Visual Studio have installed the latest Patch Tuesday updates. Check Windows Update, and the Visual Studio Installer.
  2. Download and install the 6.0.1 SDK (64-bit download, 32-bit download).
  3. Create a global.json file with the contents @RussKie commented here, and put that file beside your project's .sln file.

That's it. When you debug your app you may notice it's still loading 6.0.2 DLLs, but when you run the app on a system with the 6.0.1 runtime, it will work/not crash.

absid89 commented 2 years ago

I believe you can install 6.0.1 from https://dotnet.microsoft.com/en-us/download/dotnet/6.0. In the global.json you can pin the SDK to 6.0.1

{
  "sdk": {
    "version": "6.0.101",
    "rollForward": "disable"
  }
}

i have same problem after visual studio update. on clients installed 6.0.1 runtime, and all got a crash after run app thx, i will try your solution

kirsan31 commented 2 years ago

@EatonZ WoW - thanks for discovering this first - it will save us a certain amount of nerve cells :)))

absid89 commented 2 years ago

@EatonZ

That's it. When you debug your app you may notice it's still loading 6.0.2 DLLs, but when you run the app on a system with the 6.0.1 runtime, it will work/not crash.

thx for explain, otherwise no matter what I did, the version of the environment did not change to 6.0.1

RussKie commented 2 years ago

For an available workaround please refer to https://github.com/dotnet/core/issues/7176.

SimonCropp commented 2 years ago

so when this is fixed, my app build against the latest 6.0.* sdk will be able to run on a machine with only 6.0.0 installed?

RussKie commented 2 years ago

Any apps built on 6.0.m will work on the latest 6.0.n (where n > m). However apps built on 6.0.2+ won't work on 6.0.0 or 6.0.1.

RussKie commented 2 years ago

https://github.com/dotnet/wpf/pull/6101#issuecomment-1039089267 contains some useful info.

SimonCropp commented 2 years ago

Any apps built on 6.0.m will work on the latest 6.0.n (where n > m). However apps built on 6.0.2+ won't work on 6.0.0 or 6.0.1.

so if i interpret that correctly, if anyone wanst to leverage some new features/fixes of an sdk, it has to be considered a breaking change for the deployed app?

RussKie commented 2 years ago

Yes, in some scenarios it will be a breaking change.

SimonCropp commented 2 years ago

in some scenarios? in what scenarios would it not be considered a breaking change?

RussKie commented 2 years ago

in what scenarios would it not be considered a breaking change?

When an app built against 6.0.2+ not run on 6.0.0 or 6.0.1.

SimonCropp commented 2 years ago

i am talking from the perspective of the app producer. it would seem any time they update their sdk, they also need to force all consumers to update their runtime, hence always breaking

RussKie commented 2 years ago

The end users need to be on at least 6.0.2, after that it should BAU. That is, if an app producer builds against 6.0.2 or 6.0.6, the app would run on any runtime starting from 6.0.2.

SimonCropp commented 2 years ago

That is, if an app producer builds against 6.0.2 or 6.0.6, the app would run on any runtime starting from 6.0.2.

ok cool. that was my hope.

DavidWiseman commented 2 years ago

If I run my .NET 6 app on a machine without .NET 6 installed, I'm prompted to install it which is great. If I later compile with 6.0.2 which happens automatically just by upgrading VS. Then the app fails silently. I have to check the event viewer for an error message - do some googling and try to figure out what the problem is.

If a newer runtime is required I don't think it would be as big problem if it prompted you to install the new version. Or if this was treated as a new .NET framework version where you have to explicitly change the target framework in Visual Studio.

I guess this will be less of an issue over time as more clients have 6.0.2 installed. For now I don't want to upgrade and will use the workaround.

EatonZ commented 2 years ago

6.0.3 is out now. Is this considered fixed?

dreddy-work commented 2 years ago

6.0.3 is out now. Is this considered fixed?

It should. We will cross verify and close it. @Olina-Zhang as FYI

tomaszmalik commented 2 years ago

The issue is critical and it is not fixed in 6.0.3. It's hard to believe that we have to wait another month for that easy fix.

kirsan31 commented 2 years ago

The issue is critical and it is not fixed in 6.0.3. It's hard to believe that we have to wait another month for that easy fix.

Really? Our app build with 6.0.3 work fine on machines with 6.0.2... 🤷‍♂️

tomaszmalik commented 2 years ago

Really? Our app build with 6.0.3 work fine on machines with 6.0.2... 🤷‍♂️

That's because .NET 6.0.2 and .NET 6.0.3 has System.Windows.Forms with version 6.0.2. .NET 6.0.0 and .NET 6.0.1 has System.Windows.Forms with version 6.0.0. So error occurs for user with .NET version 6.0.0 or 6.0.1, who uses apps compiled with 6.0.2 or 6.0.3.

kirsan31 commented 2 years ago

Really? Our app build with 6.0.3 work fine on machines with 6.0.2... 🤷‍♂️

That's because .NET 6.0.2 and .NET 6.0.3 has System.Windows.Forms with version 6.0.2. .NET 6.0.0 and .NET 6.0.1 has System.Windows.Forms with version 6.0.0. So error occurs for user with .NET version 6.0.0 or 6.0.1, who uses apps compiled with 6.0.2 or 6.0.3.

And this is by design I think... https://github.com/dotnet/winforms/issues/6663#issuecomment-1039910644 https://github.com/dotnet/winforms/issues/6663#issuecomment-1040990481 https://github.com/dotnet/winforms/issues/6663#issuecomment-1041002991

tomaszmalik commented 2 years ago

And this is by design I think... #6663 (comment) #6663 (comment) #6663 (comment)

No, it's not, it's a bug. :) It seems that it would not be fixed, as it was explained here: https://github.com/dotnet/wpf/pull/6101#issuecomment-1039089267 I understand the problem, but there should be official warning and some explanation in release notes. The issue is still open ...

dreddy-work commented 2 years ago

The issue is critical and it is not fixed in 6.0.3.

@RussKie to confirm the fix propagated to 6.0.3 installer.

EatonZ commented 2 years ago

I checked and the 6.0.3 System.Windows.Forms dll is versioned 6.0.2.0. That is what they said would happen, so it appears the issues is fixed.

My advice would be to wait a while for users' computers to update with this new version before building again with 6.0.2+. Building on 6.0.1 is the safest option for now.

RussKie commented 2 years ago

The issue is critical and it is not fixed in 6.0.3. It's hard to believe that we have to wait another month for that easy fix.

That's because .NET 6.0.2 and .NET 6.0.3 has System.Windows.Forms with version 6.0.2. .NET 6.0.0 and .NET 6.0.1 has System.Windows.Forms with version 6.0.0. So error occurs for user with .NET version 6.0.0 or 6.0.1, who uses apps compiled with 6.0.2 or 6.0.3.

This is the fix. Between the bad and the worse, it was the best option available. Please refer to https://github.com/dotnet/winforms/pull/6667 and https://github.com/dotnet/wpf/pull/6101#issuecomment-1039089267 for more details as to why this is considered a fix. Sadly, if you're shipping Windows Desktop apps targeting 6.0.0 or 6.0.1 you'll need to recompile for 6.0.2 or later. Likewise, if users don't have at least 6.0.2 runtime installed, they won't be able to run your apps compiled on 6.0.2 or later.

Building on 6.0.1 is the safest option for now.

6.0.1, 6.0.2 and 6.0.3 are MSRC releases, and users are encouraged to update to the latest runtime/SDK available.

lukos commented 2 years ago

This is all very depressing. .Net is 20 years old and it seems like MS still can't get the versioning of assemblies correct. I honestly think I spent 50% of my time coding an app and the rest trying to get builds and deployments working. It is not acceptable for a company with as much experience and expertise as MS to just say, "yeah this was wrong but we'll sort it out later". Not everyone has the luxury of rebuilding things or getting customers to update runtimes as easily as that.

Not that this is the issue I had recently with my app but it leaves a really poor experience for people like me who really do like .Net and yet their first attempt at a dotnet core winforms app falls at the first hurdle and I still don't know why.

TCNOco commented 2 years ago

Adding .NET 6.0.3 as a requirement fixed the issues I was experiencing. The TcNo Account Switcher I'm working on includes a C++ fallback to verify system requirements are met, and will auto-download new runtimes. While it's not a huge issue to me, it was incredibly confusing that it just broke after updating VS/Windows...

vitek-karas commented 2 years ago

Did we consider changing the version of the Microsoft.WindowsDesktop.App framework reference to 6.0.2? That would at least declare a clear intent - the app need 6.0.2 to run. And it would provide reasonable end user experience.

Currently the app silently fails - meaning it does nothing visually - no error output, no dialog, nothing. It's really hard to diagnose what happened.

If it declared the 6.0.2 dependency, the host would provide a dialog asking the user to download the newer framework - so actionable feedback which can actually fix the problem on the user's machine.