Skip to content

Feature Request - Add AnyCPU Support #1714

Closed
@amaitland

Description

@amaitland
Member

UPDATE: Starting with release v87.1.132 the Nuget packages have been restructured to greatly simplify using AnyCPU. Issue #3319 has some specific information.

Those upgrading from versions prior to v87.1.132 shouldn't need to make any code changes.

Option 1

When targeting AnyCPU when your project has Prefer 32bit set to true then the resulting exe will be 32bit, the Nuget package checks for this and copies only the x86 files. This is the default for a number of Visual Studio project templates. No further changes are required.

To manually set Prefer 32bit open your project properties and under the build tab check prefer 32bit.

visualstudioprefer32bit

Option 2

Add a dependency resolver, this is more complicated and needs to be hooked up before any calls to classes in the CefSharp.* namespaces. Here is one method of doing this. It's important that LoadApp is not in-lined, so the calls to CefSharp are delayed long enough to hookup the Assembly Resolver

  • Add <CefSharpAnyCpuSupport>true</CefSharpAnyCpuSupport> to the first <PropertyGroup> in your project (e.g. .csproj file).
  • Implement the code below (modifying any setting that you require).
[STAThread]
public static void Main()
{
    CefRuntime.SubscribeAnyCpuAssemblyResolver();

    LoadApp();
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static void LoadApp()
{
    var settings = new CefSettings();

    Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

    var browser = new BrowserForm();
    Application.Run(browser);
}

The MinimalExample now has AnyCPU as a target to demo the CefSharpAnyCpuSupport option.

Activity

added this to the 51.0.0 milestone on Jun 17, 2016
amaitland

amaitland commented on Jun 20, 2016

@amaitland
MemberAuthor

Example WPF solution.

You must add <CefSharpAnyCpuSupport>true</CefSharpAnyCpuSupport> to the first <PropertyGroup> in your project (e.g. .csproj file).

public partial class App : Application
{
    public App()
    {
        CefRuntime.SubscribeAnyCpuAssemblyResolver();

        //Any CefSharp references have to be in another method with NonInlining
        // attribute so the assembly rolver has time to do it's thing.
        InitializeCefSharp();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void InitializeCefSharp()
    {
        var settings = new CefSettings();

        Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
    }
}

The MinimalExample now has AnyCPU as a target to demo the CefSharpAnyCpuSupport option.

amaitland

amaitland commented on Jun 20, 2016

@amaitland
MemberAuthor

I've updated the original issue at the top here to include details about adding a CefSharpAnyCpuSupport property to your project file. This is only required for AnyCPU support and will through an error as part of your build process until it's been added. The error directs people to this issue.

amaitland

amaitland commented on Aug 26, 2016

@amaitland
Author
locked and limited conversation to collaborators on Sep 8, 2016
amaitland

amaitland commented on Apr 21, 2017

@amaitland
MemberAuthor

There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "CefSharp.Core", "x86".

The above warning in your Error List is safe to ignore. If you wish to disable this warning see http://thebuildingcoder.typepad.com/blog/2013/06/processor-architecture-mismatch-warning.html

amaitland

amaitland commented on Jul 13, 2018

@amaitland
MemberAuthor

You must add <CefSharpAnyCpuSupport>true</CefSharpAnyCpuSupport> to the first <PropertyGroup> in your project (e.g. .csproj file).

Option 3

I've not tested this option in any great detail, so use at you own risk. It requires the user to have Write Permission to the applications executing folder. No special resolves or methods of loading the dlls is required. The relevant files are copied to the executing folder and unused resources deleted

  • Copies CefSharp resources from the x86 or x64 folder depending on application bitness
  • Removes x86 and x64 folders

NOTE

  • If you upgrade/downgrade you will need to manually remove the libs from the executing folder (A simple Git Cleanup would suffice)
  • This option would be best used when deploying using an installer.
//Example WinForms Code (WPF  would be very similar)
[STAThread]
public static void Main()
{
	var executingFolder = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;

	//If libcef.dll doesn't exist in our executing folder then we'll copy the files
	//For this method the user must have write permissions to the executing folder.
	if (!File.Exists(Path.Combine(executingFolder, "libcef.dll")))
	{
		var libPath = Path.Combine(executingFolder, Environment.Is64BitProcess ? "x64" : "x86");

		CopyFilesRecursively(new DirectoryInfo(libPath), new DirectoryInfo(executingFolder));

		Directory.Delete("x86", recursive: true);
		Directory.Delete("x64", recursive: true);
	}

	LoadApp();
}

//https://stackoverflow.com/a/58779/4583726
private static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)
{
	foreach (DirectoryInfo dir in source.GetDirectories())
	{
		CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
	}

	foreach (FileInfo file in source.GetFiles())
	{
		file.CopyTo(Path.Combine(target.FullName, file.Name));
	}
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static void LoadApp()
{
	//Perform dependency check to make sure all relevant resources are in our output directory.
	var settings = new CefSettings();

	Cef.Initialize(settings, performDependencyCheck: false, browserProcessHandler: null);

	var browser = new BrowserForm();
	Application.Run(browser);
}
amaitland

amaitland commented on Oct 3, 2019

@amaitland
MemberAuthor
amaitland

amaitland commented on Apr 8, 2021

@amaitland
MemberAuthor

Starting with release v87.1.132 there is another option for AnyCPU support.

Option 4

  • Unlike the other options don't set CefSharpAnyCpuSupport in your project file.
  • Make sure your application has an app.config
  • Ensure your copy of Visual Studio has the Web Developer Tools installed OR
  • Install the MSBuild.Microsoft.VisualStudio.Web.targets Nuget package (whilst Microsoft is included in the package name, this package is released by a 3rd party).

The resulting app.config file (e.g. CefSharp.MinimalExample.OffScreen.exe.config) will look something like below.
The Microsoft.Web.Publishing.Tasks.dll contains a transform which modifies your app.config as part of the build process adding entries that resolve the CefSharp.Core.Runtime.dll at runtime. Note this doesn't modify your app.config in your project root, only the generated version in your bin folder.

THIS IS AN EXAMPLE OF THE GENERATED APP.CONFIG, NO CODE CHANGES ARE REQUIRED

<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup>
  <!--<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="MyCefSharpTargetDir"/>
    </assemblyBinding>
  </runtime>-->
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="CefSharp.Core.Runtime" processorArchitecture="x86" publicKeyToken="40c4b6fc221f4138" culture="neutral"/>
        <codeBase version="89.0.170.0" href="x86/CefSharp.Core.Runtime.dll"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="CefSharp.Core.Runtime" processorArchitecture="amd64" publicKeyToken="40c4b6fc221f4138" culture="neutral"/>
        <codeBase version="89.0.170.0" href="x64/CefSharp.Core.Runtime.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

</configuration>
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

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @amaitland

        Issue actions

          Feature Request - Add AnyCPU Support · Issue #1714 · cefsharp/CefSharp