我正在尝试让CefSharp.Wpf
在VSTO Office加载项中工作,该加载项默认情况下已启用卷影副本,但是我无法找到禁用它的方法。在运行时,程序集被复制到一个临时位置(AppData\local\assembly
......等);这样做的问题是,并非所有需要的文件都复制到CefSharp的程序集位置。实际上,在首次运行时,或者在为AppDomain创建新的卷影副本位置时,都会引发异常,因为甚至找不到cefsharp.core.dll
。但是,此后,将创建cef程序集位置,但仅使用cefsharp.core.dll
,因此任何连续执行都将找到cefsharp.core.dll
,但是由于应用程序正在使用该卷影副本位置,因此不会找到其依赖项作为组装基地。
我尝试了几种方法来尝试显式设置库的位置,但是收效甚微:
namespace OutlookTools
{
public partial class AdvPrint : Window
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetDllDirectory(string lpPathName);
// This resolves to the original build folder
private static string cefFolder = new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)).LocalPath;
public AdvPrint()
{
SetDllDirectory(cefFolder);
InitializeCefSharp(); // First run exception is thrown here, before function is even executed (No cefsharp.core.dll)
InitializeComponent();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void InitializeCefSharp()
{
CefSharpSettings.SubprocessExitIfParentProcessClosed = true;
var settings = new CefSettings();
settings.BrowserSubprocessPath = Path.Combine(cefFolder, "CefSharp.BrowserSubprocess.exe");
settings.LocalesDirPath = Path.Combine(cefFolder, "locales");
settings.ResourcesDirPath = cefFolder;
// Make sure you set performDependencyCheck false
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null); // Final exception is thrown here
}
}
}
namespace OutlookTools
{
public partial class AdvPrint : Window
{
// This resolves to the original build folder
private static string cefFolder = new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)).LocalPath;
public AdvPrint(Outlook.MailItem mailItem)
{
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
InitializeCefSharp(); // First run exception is thrown here, before function is even executed (No cefsharp.core.dll)
InitializeComponent();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void InitializeCefSharp()
{
CefSharpSettings.SubprocessExitIfParentProcessClosed = true;
var settings = new CefSettings();
settings.BrowserSubprocessPath = Path.Combine(cefFolder, "CefSharp.BrowserSubprocess.exe");
settings.LocalesDirPath = Path.Combine(cefFolder, "locales");
settings.ResourcesDirPath = cefFolder;
// Make sure you set performDependencyCheck false
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null); // Final exception is thrown here
}
/// <summary>
/// Will attempt to load missing assemblies from build folder
/// </summary>
private static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
if (args.Name.StartsWith("CefSharp"))
{
string assemblyName = args.Name.Split(new[] { ',' }, 2)[0] + ".dll";
string subfolderPath = Path.Combine(cefFolder, assemblyName);
return File.Exists(subfolderPath) ? Assembly.LoadFile(subfolderPath) : null;
}
return null;
}
}
}
public partial class AdvPrint : Window
{
// This resolves to the original build folder
private static string cefFolder = new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)).LocalPath;
public AdvPrint(Outlook.MailItem mailItem)
{
var libraryLoader = new CefLibraryHandle(Path.Combine(cefFolder, "libcef.dll"));
//Calls to CEF cannot be made directly in this method, doing so would
//attempt to load `CefSharp.Core` which requires `libcef.dll` which
//we are now dynamically loading from our own folder.
InitializeCefSharp(); // First run exception is thrown here, before function is even executed (No cefsharp.core.dll)
libraryLoader.Dispose();
InitializeComponent();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void InitializeCefSharp()
{
CefSharpSettings.SubprocessExitIfParentProcessClosed = true;
var settings = new CefSettings();
settings.BrowserSubprocessPath = Path.Combine(cefFolder, "CefSharp.BrowserSubprocess.exe");
settings.LocalesDirPath = Path.Combine(cefFolder, "locales");
settings.ResourcesDirPath = cefFolder;
// Make sure you set performDependencyCheck false
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null); // Final exception is thrown here
}
}
}
我设置了BrowserSubprocessPath
,LocalesDirPath
,ResourcesDirPath
,这似乎解决了大多数运行时错误,但是现在我遇到了这个模糊的异常:
System.IO.FileNotFoundException:'无法加载文件或程序集'CefSharp,版本= 73.1.130.0,区域性=中性,PublicKeyToken = 40c4b6fc221f4138'或其依赖项之一。系统找不到指定的文件。'
我肯定知道所有依赖项都在build文件夹中,并且我可以顺利运行CefSharp.MinimalExample
项目。似乎都指向正在使用的卷影复制程序集(如果我不覆盖设置中的BrowserSubprocessPath
,则可以看到它最初指向C:....\AppData\local\assembly\some\long\temp\path
)。