// Copyright © 2015 The CefSharp Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; namespace CefSharp { /// /// DependencyChecker provides a known list of Cef/CefSharp dependencies and /// provides helper methods to check for their existance. /// public static class DependencyChecker { /// /// en-US Locales pak file location /// public const string LocalesPackFile = @"locales\en-US.pak"; /// /// List of Cef Dependencies /// public static string[] CefDependencies = { // CEF core library "libcef.dll", // Unicode support "icudtl.dat", // V8 native mapping files, see // https://groups.google.com/a/chromium.org/forum/#!topic/chromium-packagers/75J9Y1vIc_E // http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=12580 // "natives_blob.bin" was removed // https://bugs.chromium.org/p/v8/issues/detail?id=7624#c60 "snapshot_blob.bin", "v8_context_snapshot.bin" }; /// /// List of Cef Resources (pack files) /// public static string[] CefResources = { // Pack Files // Note: Contains WebKit image and inspector resources. "devtools_resources.pak", "cef.pak", "cef_extensions.pak", "cef_100_percent.pak", "cef_200_percent.pak" }; /// /// List of Optional CEF Dependencies /// public static string[] CefOptionalDependencies = { // Angle and Direct3D support // Note: Without these components HTML5 accelerated content like 2D canvas, 3D CSS and WebGL will not function. "libEGL.dll", "libGLESv2.dll", "d3dcompiler_47.dll", //Crashpad support "chrome_elf.dll" }; /// /// List of CefSharp Dependencies /// public static string[] CefSharpDependencies = { "CefSharp.Core.dll", "CefSharp.dll" }; /// /// List of CefSharp.BrowserSubprocess.exe dependencies. /// public static string[] BrowserSubprocessDependencies = { "CefSharp.BrowserSubprocess.Core.dll", "CefSharp.Core.dll", "CefSharp.dll", "icudtl.dat", "libcef.dll" }; /// /// CheckDependencies iterates through the list of Cef and CefSharp dependencines /// relative to the path provided and returns a list of missing ones /// /// check to see if optional dependencies are present /// Is loading of pack files disabled? /// path to check for dependencies /// The path to the resources directory, if empty the Executing Assembly path is used. /// The path to a separate executable that will be launched for sub-processes. /// The locale pack file e.g. /// List of missing dependencies, if all present an empty List will be returned public static List CheckDependencies(bool checkOptional, bool packLoadingDisabled, string path, string resourcesDirPath, string browserSubProcessPath, string localePackFile = LocalesPackFile) { var missingDependencies = new List(); missingDependencies.AddRange(CheckDependencyList(path, CefDependencies)); if (!packLoadingDisabled) { missingDependencies.AddRange(CheckDependencyList(resourcesDirPath, CefResources)); } if (checkOptional) { missingDependencies.AddRange(CheckDependencyList(path, CefOptionalDependencies)); } missingDependencies.AddRange(CheckDependencyList(path, CefSharpDependencies)); if (!File.Exists(browserSubProcessPath)) { missingDependencies.Add(browserSubProcessPath); } var browserSubprocessDir = Path.GetDirectoryName(browserSubProcessPath); if (browserSubprocessDir == null) { missingDependencies.AddRange(BrowserSubprocessDependencies); } else { missingDependencies.AddRange(CheckDependencyList(browserSubprocessDir, BrowserSubprocessDependencies)); } // If path is not rooted (doesn't start with a drive letter + folder) // then make it relative to the executing assembly. var localePath = Path.IsPathRooted(localePackFile) ? localePackFile : Path.Combine(path, localePackFile); if (!File.Exists(localePath)) { missingDependencies.Add(localePackFile); } return missingDependencies; } /// /// Loop through dependencies and add to the returned missing dependency list if not found. /// /// The directory of the dependencies, or the current directory if null. /// The dependencies to check. /// List of missing dependencies, if all present an empty List will be returned private static List CheckDependencyList(string dir, IEnumerable files) { var missingDependencies = new List(); foreach (var file in files) { var filePath = string.IsNullOrEmpty(dir) ? file : Path.Combine(dir, file); if (!File.Exists(filePath)) { missingDependencies.Add(filePath); } } return missingDependencies; } /// /// Checks if all Cef and CefSharp dependencies were found relative to the Executing Assembly. /// Shortcut method that calls , throws an Exception if not files are missing. /// /// The locale, if empty then en-US will be used. /// The path to the locales directory, if empty locales\ will be used. /// The path to the resources directory, if empty the Executing Assembly path is used. /// Is loading of pack files disabled? /// The path to a separate executable that will be launched for sub-processes. /// Throw when not all dependencies are present public static void AssertAllDependenciesPresent(string locale = null, string localesDirPath = null, string resourcesDirPath = null, bool packLoadingDisabled = false, string browserSubProcessPath = "CefSharp.BrowserSubProcess.exe") { string path; Uri pathUri; if (Uri.TryCreate(browserSubProcessPath, UriKind.Absolute, out pathUri) && pathUri.IsAbsoluteUri) { path = Path.GetDirectoryName(browserSubProcessPath); } else { var executingAssembly = Assembly.GetExecutingAssembly(); path = Path.GetDirectoryName(executingAssembly.Location); } if (string.IsNullOrEmpty(locale)) { locale = "en-US"; } if (string.IsNullOrEmpty(localesDirPath)) { localesDirPath = @"locales"; } if (string.IsNullOrEmpty(resourcesDirPath)) { resourcesDirPath = path; } var missingDependencies = CheckDependencies(true, packLoadingDisabled, path, resourcesDirPath, browserSubProcessPath, Path.Combine(localesDirPath, locale + ".pak")); if (missingDependencies.Count > 0) { var builder = new StringBuilder(); builder.AppendLine("Unable to locate required Cef/CefSharp dependencies:"); foreach (var missingDependency in missingDependencies) { builder.AppendLine("Missing:" + missingDependency); } builder.AppendLine("Executing Assembly Path:" + path); throw new Exception(builder.ToString()); } } } }