Skip to content

Feature Request - ARM64 support on .NET Framework 4.8.1 #4155

Description

@simplejackcoder

Bulk of the work to support Windows ARM64 is done. The only feature that will help is if CefSharp could also be compiled for .NET Framework ARM64 support.

It should merely be recompiling the managed components and the managed C++ components but leaving the rest of the native parts unchanged.

This will allow applications that are running on .NET Framework 4.8.1 on Windows 11 ARM64 to work flawlessly.

Activity

  1. kpreisser commented on Jul 16, 2022

    @kpreisser
    Contributor

    Note that using arm64 for C++/CLI projects targeting .NET Framework seems to require VS 2022 17.3 and using the v143 toolset, as that includes an ARM64 version of mscoree.lib. However, the actual .NET target framework of the project can be a lower one, e.g. .NET Framework 4.5.2.

    For regular .NET Framework projects, using arm64 as PlatformType seems to already work with VS 2019 (16.11), even for Exe projects when using a lower target framework like 4.5.2.

    I think that once we can use VS 2022 17.3 to build CefSharp (with AppVeyor), adding ARM64 support for .NET Framework would be possible in principle without changing the target framework of the projects (except for the C++/CLI projects which would need to use the C++ v143 toolset for arm64).

    The only open points I can think of is where the process architecture needs to be determined. For example, DependencyChecker needs to check for arm64 to exclude D3DCompiler_47.dll from the files list (#3841), but RuntimeInformation.ProcessArchitecture is only available since .NET Framework 4.7.1.

    Also, class CefRuntime uses Environment.Is64BitProcess() to distinguish between x86 and x64, which would incorrectly result in x64 when running as arm64, but that seems to only be used for support of AnyCPU applications which wouldn't run as arm64 anyway (AnyCPU apps run either as x86 (if Prefer32Bit is set) or as x64 on Windows 11 Version 22H2 ARM64, even when targeting .NET Framework 4.8.1).

  2. driver1998 commented on Jul 27, 2022

    @driver1998

    AnyCPU apps can be run as ARM64 (or any other architecture, excluding ARM32 since .NET Framework ARM32 is not available) with start /machine <arch> your-app.exe in Windows 11 22H2. Not sure about other ways of doing this.

    One possible workaround might be just P/Invoke IsWow64Process2 (Note x64 on ARM64 is not considered as WOW64 process so pProcessMachine would be IMAGE_FILE_MACHINE_UNKNOWN), and GetProcessInformation with ProcessInformationClass = ProcessMachineTypeInfo (which detects x64 on ARM64 correctly but only available in Windows 11)

  3. kpreisser commented on Jul 27, 2022

    @kpreisser
    Contributor

    Hi,

    AnyCPU apps can be run as ARM64 (or any other architecture, excluding ARM32 since .NET Framework ARM32 is not available) with start /machine your-app.exe in Windows 11 22H2.

    Thank you for the info! You are right, with this command I was able to run an AnyCPU .NET Framework application (targeting 4.7.2) as ARM64 (when Prefer32Bit was false). So it seems we also need to consider the case in CefRuntime for ARM64.

    One possible workaround might be just P/Invoke IsWow64Process2 (Note x64 on ARM64 is not considered as WOW64 process so pProcessMachine would be IMAGE_FILE_MACHINE_UNKNOWN), and GetProcessInformation with ProcessInformationClass = ProcessMachineTypeInfo (which detects x64 on ARM64 correctly but only available in Windows 11)

    Alternatively, maybe we could also try to use reflection to get RuntimeInformation.ProcessArchitecture to determine the process architecture. If this is not available, it must be an older .NET Framework version (before 4.7.1) that cannot run as ARM64, where then Environment.Is64BitProcess can be used.

    (For IsWow64Process2, note that it is only available starting with Windows 10 build 16299 (RS3).)

  4. driver1998 commented on Jul 27, 2022

    @driver1998

    The command should be start /machine arm64 your-app.exe but I guess you've already figured that out ;).

  5. amaitland commented on Oct 25, 2022

    @amaitland
    Member

    Note that using arm64 for C++/CLI projects targeting .NET Framework seems to require VS 2022 17.3 and using the v143 toolset, as that includes an ARM64 version of mscoree.lib

    Adding the required variants to the project files should be relatively easy. If someone wants to kick this off by creating a PR that only gets the basics building then by all means feel free. Avoid package changes for now.

    The packaging will be a problem, upgrading to VS2022 will either require updating the minimum required VC++ runtime or building with the older v142 tools assuming we can find a build host with support.

    I'd rather avoid upgrading the minimum VC++ version for x86 and x64, so that's something we'll need to look into.

    Issue cefsharp/cef-binary#93 will also need to be resolved before any sort of package can be created.

    For testing purposes the examples already use the chromiumembeddedframework.runtime packages.

    The only open points I can think of is where the process architecture needs to be determined. For example, DependencyChecker needs to check for arm64 to exclude D3DCompiler_47.dll from the files list (#3841), but RuntimeInformation.ProcessArchitecture is only available since .NET Framework 4.7.1.

    Seeing if we can use reflection seems like a reasonable first step for this and CefRuntime.

  6. amaitland commented on Oct 25, 2022

    @amaitland
    Member

    As with ARM64 support for .Net 5.0+ I'll be relying on the community to contribute and test as I don't have an ARM64 device.

  7. amaitland commented on Dec 1, 2023

    @amaitland
    Member

    The packaging will be a problem, upgrading to VS2022 will either require updating the minimum required VC++ runtime or building with the older v142 tools assuming we can find a build host with support.

    Issue #4640 will track upgrading to VC++ 2022 (using VS2022 as the build version). If CEF starts using C++20 features then we will be forced to upgrade.

  8. stojy commented on Jun 20, 2025

    @stojy

    Has there been any movement towards building CefSharp that supports ARM64? It certainly would be a very nice feature!

    Out of interest, is the blocker the VS22 upgrade, v143 toolset, or relying on .net 4.7.1 for RuntimeInformation.ProcessArchitecture?

  9. amaitland commented on Jun 20, 2025

    @amaitland
    Member

    Has there been any movement towards building CefSharp that supports ARM64?

    Not that I'm aware of. You can of course use .Net 5.0 or greater

    This is currently blocked on #4640

  10. amaitland commented on Aug 24, 2025

    @amaitland
    Member

    This is currently blocked on #4640

    This issue has been resolved.

    It should now be possible to implement this if someone wants to contribute a PR.

  11. stojy commented on Jul 7, 2026

    @stojy

    Hi @amaitland

    I appreciate yours and @jamescharters effort in getting this one across the line.

    Do you have an ETA when the new PR #5267 will be merged in and released?

    Thanks.

  12. amaitland commented on Jul 7, 2026

    @amaitland
    Member

    No ETA. The build is passing on CI. I have no means of testing it.

    Once it's been tested it can be merged.

  13. 2 remaining items

  14. stojy commented on Jul 14, 2026

    @stojy

    Hi @amaitland, I'm just following up on my earler post.

    Do you have a pre-release nuget package available with the ARM support? If so, I'm happy to test it.

  15. amaitland commented on Jul 15, 2026

    @amaitland
    Member

    Thanks for the offer. Once I've pushed M150 I'll see about a set of packages to test.

    Hopefully on the weekend

  16. amaitland commented on Jul 25, 2026

    @amaitland
    Member

    MyGet has unfortunately been having issues, builds have more often than not failed to push packages.

    Seems like it's back up (though they have had recurring issues lately, so if you have issues then we'll have to look at another option).

    https://ci.appveyor.com/project/cefsharp/cefsharp/builds/54435032

    https://www.myget.org/F/cefsharp/api/v3/index.json

    Should be version 150.0.110-CI5572

  17. stojy commented on Jul 27, 2026

    @stojy

    I've managed to install the v150 package ok and code builds without issue.

    As per the attached image, it unfortunately it doesn't create/copy the cef binaries into the bin\debug\arm64 folder.
    Image

    Fortunately, it's an easy one to reproduce by creating a new WPF .net framework project and then add the CefSharp.Wpf package. The x64 and x86 folders are correctly populated, but the arm64 folder and contents are missing. If it helps, I've attached the verbose build output from a fresh project.

    Hopefully it's something simple.

    WpfCefFramework - build output.txt

  18. stojy commented on Jul 27, 2026

    @stojy

    Some good news though, I've manually copied the binaries into the arm64 folder.. and CefSharp/chromium now works on ARM64 running .net framework :)

  19. amaitland commented on Jul 31, 2026

    @amaitland
    Member

    Thanks for testing, quick check and it does appear that there are some missing entries in NuGet/CefSharp.Common.targets for AnyCPU, so they will need to be added.

  20. stojy commented on Aug 7, 2026

    @stojy

    hi @amaitland

    *.targets files are not something I've had a lot of experience. with. But please let me know if there's anything I can do to assist to get this across the line.

    And hopefully you'll be able to verify any changes locally regarding the nuget installation as I don't believe this relies on having an ARM CPU.

  21. M4ttsson commented on Aug 21, 2026

    @M4ttsson
    Contributor

    Hi,

    We was following this and was very happy about all the progress during summer. I have also tested the PR changes on an arm machine using a test wpf client. As you said the targets need to be updated for AnyCPU. When using AnyCPU I also had to add <PreferNativeArm64>true</PreferNativeArm64> to my project to avoid x64 emulation on my test machine.

    Thanks for the good work.

    Here are the changes I used to build the nugets locally to test with. Let me know if I can help with something to get this approved.

    diff --git a/NuGet/CefSharp.Common.targets b/NuGet/CefSharp.Common.targets
    index 3a54a6a0..63899918 100644
    --- a/NuGet/CefSharp.Common.targets
    +++ b/NuGet/CefSharp.Common.targets
    @@ -118,6 +118,7 @@
         <CefSharpTargetDir Condition="'$(CefSharpTargetDir)' != '' AND !HasTrailingSlash('$(CefSharpTargetDir)')">$(CefSharpTargetDir)\</CefSharpTargetDir>
         <CefSharpTargetDirAnyCpu32>$(CefSharpTargetDir)x86\</CefSharpTargetDirAnyCpu32>
         <CefSharpTargetDirAnyCpu64>$(CefSharpTargetDir)x64\</CefSharpTargetDirAnyCpu64>
    +    <CefSharpTargetDirAnyCpuArm64>$(CefSharpTargetDir)arm64\</CefSharpTargetDirAnyCpuArm64>
         <!--
         For Sdk Projects the PlatformTarget is unreliable (https://github.com/dotnet/sdk/issues/1560)
         When our targets file is imported $(PlatformTarget) will be x86 when the Platform is infact AnyCPU.
    @@ -232,6 +233,12 @@
                   <PublishState>Included</PublishState>
                   <Visible>false</Visible>
                 </None>
    +            <None Include="@(CefRedistArm64)">
    +              <Link>$(CefSharpTargetDirAnyCpuArm64)%(RecursiveDir)%(FileName)%(Extension)</Link>
    +              <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    +              <PublishState>Included</PublishState>
    +              <Visible>false</Visible>
    +            </None>
                 <None Include="@(CefSharpCommonBinaries32)">
                   <Link>$(CefSharpTargetDirAnyCpu32)%(RecursiveDir)%(FileName)%(Extension)</Link>
                   <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    @@ -244,6 +251,12 @@
                   <PublishState>Included</PublishState>
                   <Visible>false</Visible>
                 </None>
    +            <None Include="@(CefSharpCommonBinariesArm64)">
    +              <Link>$(CefSharpTargetDirAnyCpuArm64)%(RecursiveDir)%(FileName)%(Extension)</Link>
    +              <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    +              <PublishState>Included</PublishState>
    +              <Visible>false</Visible>
    +            </None>
                 <!--
                 Include CefSharp.dll and CefSharp.Core.dll (we only need CefSharp.dll but it's easier to include both)
                 in the arch specific folders as required by the BrowserSubProcess.
    @@ -260,6 +273,12 @@
                   <PublishState>Included</PublishState>
                   <Visible>false</Visible>
                 </None>     
    +            <None Include="@(CefSharpCommonManagedDll)">
    +              <Link>$(CefSharpTargetDirAnyCpuArm64)%(RecursiveDir)%(FileName)%(Extension)</Link>
    +              <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    +              <PublishState>Included</PublishState>
    +              <Visible>false</Visible>
    +            </None>
               </ItemGroup>
             </When>
             <!-- x86 and Win32-->
    @@ -335,6 +354,13 @@
                   <Visible>false</Visible>
     			  <IncludeInVsix>true</IncludeInVsix>
                 </Content>
    +            <Content Include="@(CefRedistArm64)">
    +              <Link>$(CefSharpTargetDirAnyCpuArm64)%(RecursiveDir)%(FileName)%(Extension)</Link>
    +              <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    +              <PublishState>Included</PublishState>
    +              <Visible>false</Visible>
    +			  <IncludeInVsix>true</IncludeInVsix>
    +            </Content>
                 <Content Include="@(CefSharpCommonBinaries32)">
                   <Link>$(CefSharpTargetDirAnyCpu32)%(RecursiveDir)%(FileName)%(Extension)</Link>
                   <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    @@ -349,6 +375,13 @@
                   <Visible>false</Visible>
     			  <IncludeInVsix>true</IncludeInVsix>
                 </Content>
    +            <Content Include="@(CefSharpCommonBinariesArm64)">
    +              <Link>$(CefSharpTargetDirAnyCpuArm64)%(RecursiveDir)%(FileName)%(Extension)</Link>
    +              <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    +              <PublishState>Included</PublishState>
    +              <Visible>false</Visible>
    +			  <IncludeInVsix>true</IncludeInVsix>
    +            </Content>
                 <!--
                 Include CefSharp.dll and CefSharp.Core.dll (we only need CefSharp.dll but it's easier to include both)
                 in the arch specific folders as required by the BrowserSubProcess.
    @@ -367,6 +400,13 @@
                   <Visible>false</Visible>
     			  <IncludeInVsix>true</IncludeInVsix>
                 </Content>     
    +            <Content Include="@(CefSharpCommonManagedDll)">
    +              <Link>$(CefSharpTargetDirAnyCpuArm64)%(RecursiveDir)%(FileName)%(Extension)</Link>
    +              <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    +              <PublishState>Included</PublishState>
    +              <Visible>false</Visible>
    +			  <IncludeInVsix>true</IncludeInVsix>
    +            </Content>
               </ItemGroup>
             </When>
             <!-- x86 and Win32-->
  22. stojy commented on Aug 28, 2026

    @stojy

    Hi @amaitland

    Sorry to nag, but do you know when you could merge in the changes from @M4ttsson and release a new nuget package?

    I can certainly verify it very quickly.

    Thanks

  23. amaitland commented on Aug 28, 2026

    @amaitland
    Member

    Someone is welcome to submit a PR with the proposed changes, just target https://github.com/cefsharp/CefSharp/tree/netarm64

  24. M4ttsson commented on Aug 31, 2026

    @M4ttsson
    Contributor

    Hi @amaitland,

    I have submitted #5288, targets the netarm64 branch. I verified again today that the project builds properly using both AnyCpu and Arm64.

    Please let me know if there is something more I can do or if I should update something in the PR.

  25. amaitland commented on Sep 18, 2026

    @amaitland
    Member

    Try the 152 release, it includes these changes

  26. stojy commented on Sep 24, 2026

    @stojy

    Thanks everyone. I've just integrated v152 and it looks perfect. We now have an ARM native .net framework build :)

  27. M4ttsson commented on Sep 25, 2026

    @M4ttsson
    Contributor

    I've also upgraded to v152 now and everything works. Thanks. :)

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions