启用程序集卷影副本时出现FileNotFound异常

时间:2019-06-30 06:50:28

标签: cefsharp

我正在尝试让CefSharp.Wpf在VSTO Office加载项中工作,该加载项默认情况下已启用卷影副本,但是我无法找到禁用它的方法。在运行时,程序集被复制到一个临时位置(AppData\local\assembly ......等);这样做的问题是,并非所有需要的文件都复制到CefSharp的程序集位置。实际上,在首次运行时,或者在为AppDomain创建新的卷影副本位置时,都会引发异常,因为甚至找不到cefsharp.core.dll。但是,此后,将创建cef程序集位置,但仅使用cefsharp.core.dll,因此任何连续执行都将找到cefsharp.core.dll,但是由于应用程序正在使用该卷影副本位置,因此不会找到其依赖项作为组装基地。

我尝试了几种方法来尝试显式设置库的位置,但是收效甚微:

  • kernel32 SetDllDirectory
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
        }
    }
}

我设置了BrowserSubprocessPathLocalesDirPathResourcesDirPath,这似乎解决了大多数运行时错误,但是现在我遇到了这个模糊的异常:

  

System.IO.FileNotFoundException:'无法加载文件或程序集'CefSharp,版本= 73.1.130.0,区域性=中性,PublicKeyToken = 40c4b6fc221f4138'或其依赖项之一。系统找不到指定的文件。'

我肯定知道所有依赖项都在build文件夹中,并且我可以顺利运行CefSharp.MinimalExample项目。似乎都指向正在使用的卷影复制程序集(如果我不覆盖设置中的BrowserSubprocessPath,则可以看到它最初指向C:....\AppData\local\assembly\some\long\temp\path)。

0 个答案:

没有答案