CefSharp.Wpf加载触发FileLoadException 依赖路径配置咨询
问题根因
CefSharp的依赖分为两类,两类的查找逻辑完全独立,常规的AssemblyResolve处理只能覆盖第一类:
- 纯托管程序集:包括
CefSharp.Wpf.dll、CefSharp.dll、CefSharp.Core.dll,这类文件的加载可以通过AppDomain.AssemblyResolve事件自定义加载路径,也是你目前已经处理完成的部分。 - 混合程序集+原生CEF依赖:
CefSharp.Core.Runtime.dll是混合架构程序集,加载时会直接拉起CEF的全套非托管二进制(libcef.dll、chrome_elf.dll、资源文件、架构相关扩展模块等),这部分依赖的查找走Windows原生DLL搜索规则,完全不经过.NET的AssemblyResolve事件管道。由于当前进程入口是MSAccess.exe,原生搜索逻辑默认优先遍历Office安装目录,找不到你部署路径下的文件就会抛出FileLoadException。
可落地解决方案
方案1(推荐,稳定性最高):初始化前修改原生DLL搜索目录
在你的OCX控件加载逻辑最前端,任何CefSharp相关类型被访问、任何CefSharp方法被调用之前,执行以下操作:
- 引入Windows原生API的P/Invoke声明:
using System.Runtime.InteropServices; [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetDllDirectory(string lpPathName); - 调用API将CefSharp的完整部署目录加入最高优先级的原生DLL搜索路径,替换
cefDeployRoot为你存放所有CefSharp文件(托管DLL、原生DLL、资源文件夹全部放这个目录下,不要嵌套)的绝对路径:string cefDeployRoot = @"C:\你的实际Cef部署路径"; SetDllDirectory(cefDeployRoot); - 补全
AssemblyResolve事件对CefSharp.Core.Runtime的加载逻辑,不要留空:AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { string assemblyName = new AssemblyName(args.Name).Name; string targetPath = Path.Combine(cefDeployRoot, $"{assemblyName}.dll"); if (File.Exists(targetPath)) { return Assembly.LoadFrom(targetPath); } return null; };
完成以上配置后再初始化CefSettings、实例化ChromiumWebBrowser即可。
方案2:修改进程级PATH环境变量
如果方案1因为多组件DLL路径冲突无法使用,可以在初始化前将Cef部署目录追加到当前进程的PATH变量最前端,Windows原生DLL搜索会遍历PATH下的所有目录:
string cefDeployRoot = @"C:\你的实际Cef部署路径"; string existingPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("PATH", $"{cefDeployRoot}{Path.PathSeparator}{existingPath}", EnvironmentVariableTarget.Process);
该方案同样需要配合补全的AssemblyResolve事件加载所有托管/混合程序集。
方案3:手动预加载核心依赖
如果以上两个方案仍有加载异常,可以在初始化前手动调用LoadLibrary API把Cef目录下的核心原生DLL提前加载到进程内存,后续CEF初始化时会直接复用已加载的模块,不会再触发目录查找:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern IntPtr LoadLibrary(string lpFileName); // 初始化阶段执行 string[] coreNativeDlls = new[] {"chrome_elf.dll", "libcef.dll", "v8.dll", "libGLESv2.dll"}; foreach (string dll in coreNativeDlls) { LoadLibrary(Path.Combine(cefDeployRoot, dll)); }
避坑注意事项
- 所有路径配置、事件注册、API调用必须在第一次触碰任何CefSharp类型之前完成:哪怕只是写了一句实例化ChromiumWebBrowser的代码之前没配置路径,都会触发CefSharp内部的静态构造函数提前加载依赖,后续再改路径完全失效。
- 严格匹配架构:32位版本的MS Access必须部署x86版本的CefSharp,64位MS Access必须部署x64版本,架构不匹配抛出的异常和路径缺失完全一致,排查时优先确认这点。
- 部署文件要完整:CefSharp运行不仅需要几个DLL,还要把对应版本的
locales文件夹、swiftshader文件夹、icudtl.dat、cef.pak等资源文件全部放到部署目录,缺任何一个文件都会报依赖加载失败。 - 不要把CefSharp文件放到Office安装目录:Office更新时会清理非官方安装文件,同时目录默认有权限限制,很容易出现偶发加载失败。
内容的提问来源于stack exchange,提问作者Nostromo
相关产品推荐
相关产品推荐

