Skip to content

Allow the use of .NET Core 10#4331

Merged
mhsmith merged 29 commits into
beeware:mainfrom
freakboy3742:win-arm64
Apr 23, 2026
Merged

Allow the use of .NET Core 10#4331
mhsmith merged 29 commits into
beeware:mainfrom
freakboy3742:win-arm64

Conversation

@freakboy3742

@freakboy3742 freakboy3742 commented Apr 16, 2026

Copy link
Copy Markdown
Member

Allows the Winforms backend to use .NET Core 10, instead of .NET Framework 4.x.

This is required to add native Windows on ARM support - Windows 10 and 11 both provide .NET Framework 4.x (aka netfx) out of the box, but on ARM machines, it's an x86-64 build.

This adds in a loader configuration that will try to use .NET Core 10; if .NET 10 can't be found, it will try to fall back on .NET Framework 4.x. When running on ARM with a native ARM Python interpreter, this fallback will fail, so an error is raised.

In addition to the .NET loading changes, the changes in this PR are:

  • Changes in class names for status icons
  • Windows not accurately restoring the window size when returning from FULLSCREEN or PRESENTATION.
  • Fixes to the testbed due to slightly different behavior in folder selection dialogs
  • The need for an ARM binary for WebView2 (and related changes to packaging so we have a py3-none-win_arm64 and py3-none-win_amd64 binary wheels.

With the changes in this PR, the testbed passes to completion in my test environment with a small number of errors related to discrepancies caused by the virtualisation environment (discrepancies between \\drive\location and z:\location path descriptions).

However, the testbed doesn't pass using the windows-11-arm environment, as that runner is configured as a non-interactive/headless environment. This means that no window ever gains focus, and we have no ability to test focus changes, dialog display, etc. See actions/runner-images#14049 for details.

So - this PR does a full CI pass on both .NET Framework 4.x and .NET Core 10 on Windows/x86-64, validating that the .NET Core APIs work; but only does a basic "does the app start?" test for Windows/ARM64.

Two design decisions implicit in this PR:

  • We are continuing to support .NET Framework 4.x. This is available by default on Windows 10 and 11, so it means all Toga apps will Just Work. The .NET Desktop runtime is widely installed, but isn't guaranteed to be installed. It would definitely be easier to only support .NET 10, but I'm not sure that's a great user experience. We can add a "this app requires .NET 10" to an MSI installer - but we can't easily bundle .NET 10 with an MSI installer (at least, not in a way that yields a single simple MSI).
  • We will continuing to support Windows 10. Win10 is strictly EOL, so we could drop it. If we did, I think we can go back to a pure Python Winforms wheel. The binary wheel is only needed because Windows 10 doesn't include the WebView2 runtime;0 Windows 11 does. If we drop Windows 10 support, we could simplify that part of the code as well.

However, my read is that Windows users are the least likely to be on the "bleeding edge" when it comes to new tech - we still get requests for restoring Windows 7/8 support - so dropping Windows 10 (even though it is EOL) is probably not a good idea quite yet.

Support for Windows/ARM64 has been merged into Briefcase; I've manually published stub binaries for Python 3.12 so that briefcase run works. See beeware/briefcase-windows-VisualStudio-template#89 for some template tweaks that are needed to tag those binaries.

Fixes #2782.

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

@freakboy3742 freakboy3742 marked this pull request as draft April 16, 2026 04:11
@freakboy3742

Copy link
Copy Markdown
Member Author

Two issues revealed by CI testing:

  1. There's a chicken and egg problem: We can't run testbed on Toga until Briefcase supports ARM; we can't run CI on Briefcase until Toga supports ARM.
  2. There are a handful of APIs that are actually different on .NET Core. This appears to be mostly an issue with MenuItem and StatusIcon objects. I'm not yet sure if the best solution is to hard switch to .NET core, or if there's a compatibility path that will allow both.

@johnzhou721

Copy link
Copy Markdown
Contributor

For the purposes of Toga, we should totally switch to .NET 10 IMHO. .NET 10 WinForms have out-of-the-box Dark Mode support, and more WinForms improvements.

Not familiar with the compatibility issues... however just giing my opinion on whether to switch to .NET. 10 instead of using older .NET.

@freakboy3742

Copy link
Copy Markdown
Member Author

The biggest compatibility issue is "Windows doesn't ship with .NET Core", so most users will run a Toga app and then get an error. It's not a hard error to fix... unless you don't have admin rights to install new software - and a lot of Toga users won't be.

@johnzhou721

Copy link
Copy Markdown
Contributor

@freakboy3742 Hmm... is it possible to bundle .NET Core with your application, then? This may need a PR to the Visual Studio template.

@johnzhou721

Copy link
Copy Markdown
Contributor

@freakboy3742 FYI: We should update to ContextMenuStrip anyways regardless of .NET 10 support status — which is available even in .NET 4.0. ContextMenu class is already flagged as "binary compatibility only" in docs: https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.contextmenu?view=windowsdesktop-10.0 — and it appears that MS has finally pulled the plug and removed it in .NET 10.

But also, since Winforms context menus aren't very native-looking as seen in the DetailedList PR, might as well get Oliver-Leigh to win32 everything for context menus and menustrips.

@freakboy3742 freakboy3742 marked this pull request as ready for review April 22, 2026 07:35
@freakboy3742 freakboy3742 requested a review from mhsmith April 22, 2026 07:35
@freakboy3742 freakboy3742 mentioned this pull request Apr 22, 2026
4 tasks
@mhsmith

mhsmith commented Apr 22, 2026

Copy link
Copy Markdown
Member
  • Win10 is strictly EOL, so we could drop it.

Not entirely: there was an option to pay for 1 year of extended support, and several ways to get it for free (I did, on my old laptop which wasn't Win11 compatible), and it looks like this will continue until 2028.

Comment thread .github/workflows/ci.yml Outdated
Comment thread docs/en/reference/platforms/windows.md Outdated
Comment thread winforms/src/toga_winforms/__init__.py Outdated
Comment thread docs/en/reference/platforms/windows.md Outdated
Comment thread testbed/tests/testbed.py Outdated
Comment thread testbed/tests/app/test_desktop.py Outdated
Comment thread winforms/src/toga_winforms/__init__.py
Comment thread winforms/src/toga_winforms/window.py
@Oliver-Leigh

Copy link
Copy Markdown
Contributor

But also, since Winforms context menus aren't very native-looking as seen in the DetailedList PR, might as well get Oliver-Leigh to win32 everything for context menus and menustrips.

@johnzhou721 This is actually on my to-do list...

freakboy3742 and others added 3 commits April 23, 2026 06:14
Co-authored-by: Malcolm Smith <smith@chaquo.com>
Co-authored-by: Malcolm Smith <smith@chaquo.com>
@freakboy3742 freakboy3742 requested a review from mhsmith April 22, 2026 22:43
@johnzhou721

Copy link
Copy Markdown
Contributor

FWIW: My earlier remark re: ContextMenu and/or other menu classes being deprecated in .NET Framework 3.1 was incorrect. It was deprecated in .NET Core 3.1, and although ContextMenuStrip etc. exists in .NET Framework 3.1 as well, it's less native, so the current approach of if-elsing .NETfx and .NETCore works, as it will allow .NET framework menus to become more native before the slightly mysterious Oliver-Leigh comes and Win32s everything.

@mhsmith mhsmith merged commit 464300c into beeware:main Apr 23, 2026
62 checks passed
@freakboy3742 freakboy3742 deleted the win-arm64 branch April 23, 2026 21:35
@johnzhou721

Copy link
Copy Markdown
Contributor

The biggest compatibility issue is "Windows doesn't ship with .NET Core", so most users will run a Toga app and then get an error. It's not a hard error to fix... unless you don't have admin rights to install new software - and a lot of Toga users won't be.

FWIW: Over a free period, I've done an experiment on my super-locked-down school laptop[1], and it looks like you can get .NET Core onto that computer[2].

  1. It seems like you need the SDK, not just the runtime. Our school has the runtime installed; clr doesn't load it.
  2. Go to the "SDK [version]" section in https://dotnet.microsoft.com/en-us/download/dotnet/10.0, look at the Windows row, and the Binaries column; download it, and unzip it in any location you have write access to.
  3. The natural step is to add the unzip location to PATH and set DOTNET_ROOT to the path you unzipped in; however, while you can override DOTNET_ROOT in your user's environment variables[3], adding it to PATH directly does not work as system environment variables comes first, and the school's already-present .NET installation conflicts with our user-unzipped one.
  4. Therefore: I had to write a Python script that has to run before I import and run toga_demo from IDLE—that prepends the SDK path to the PATH for the current process and entirely overrides DOTNET_ROOT for the current process.
  5. After that, clr/pythonnet manages to find .NET core flawlessly (and after hacking through some toga_winforms code, I got it to enable dark mode).

So I think with this knowledge should we add an option in Briefcase that essentially autodownloads a specified .NET SDK, unzips it, puts it in a convenient location, and adds a sitecustomize script that sets up the environment variables for the .NET SDK properly for the current process? If this is desired, I can file a ticket under Briefcase with more details.

[1] I'm talking like rules that automatically block Windows installer, a program that streams your screen to teachers, and of course, no admin privileges.
[2] I told the computer science teacher, and he says in a joking manner he's going to tell the high school teachers to watch out for me (while I suffer through Java...)
[3] Surprised they didn't lock that down...

@freakboy3742

Copy link
Copy Markdown
Member Author

The biggest compatibility issue is "Windows doesn't ship with .NET Core", so most users will run a Toga app and then get an error. It's not a hard error to fix... unless you don't have admin rights to install new software - and a lot of Toga users won't be.

FWIW: Over a free period, I've done an experiment on my super-locked-down school laptop[1], and it looks like you can get .NET Core onto that computer[2].

@johnzhou721 Posting long comments like this to the end of a closed pull request isn't an effective way to communicate issues. A closed pull request indicates that the work is "done". If there's new issues or concerns, that should be a new ticket.

  1. It seems like you need the SDK, not just the runtime. Our school has the runtime installed; clr doesn't load it.

There's a couple of "runtimes" - you need the desktop runtime, not just the ".NET runtime".

So I think with this knowledge should we add an option in Briefcase that essentially autodownloads a specified .NET SDK, unzips it, puts it in a convenient location, and adds a sitecustomize script that sets up the environment variables for the .NET SDK properly for the current process? If this is desired, I can file a ticket under Briefcase with more details.

We've already investigated and resolved this on the Briefcase side - Briefcase 0.4.2 will (if requested) verify that the required runtime is available.

This definitely isn't something we should be hacking around with things like a sitecustomize script. .NET core should be installed with system privileges.

@johnzhou721

Copy link
Copy Markdown
Contributor

Thank you for making this explicit. I now realize that this was a very hacky approach and not appropriate for posting at the end of a PR chain. (including installing the entire .NET SDK just because there's no standalone zip file for a .NET Desktop runtime, which implies that installing .NET Desktop Runtime is not meant to be installed standalone.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for native arm64 Windows

4 participants