From 1011f727eed5eb68e8a5303436d909b89b5d30f5 Mon Sep 17 00:00:00 2001 From: Alex Maitland Date: Tue, 23 Mar 2021 10:37:01 +1000 Subject: [PATCH] Net Core - Add DependencyChecker.netcore Specific .Net core DependencyChecker that takes care of the specifics of running under .Net Core/.Net 5.0 Later on the DependencyChecker can be unified. Issue #3388 --- CefSharp/CefSharp.netcore.csproj | 3 +- CefSharp/DependencyChecker.netcore.cs | 248 ++++++++++++++++++++++++++ 2 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 CefSharp/DependencyChecker.netcore.cs diff --git a/CefSharp/CefSharp.netcore.csproj b/CefSharp/CefSharp.netcore.csproj index 00c2ed071b..3c2eacaa66 100644 --- a/CefSharp/CefSharp.netcore.csproj +++ b/CefSharp/CefSharp.netcore.csproj @@ -28,7 +28,7 @@ - + @@ -42,6 +42,7 @@ + diff --git a/CefSharp/DependencyChecker.netcore.cs b/CefSharp/DependencyChecker.netcore.cs new file mode 100644 index 0000000000..080b1c729e --- /dev/null +++ b/CefSharp/DependencyChecker.netcore.cs @@ -0,0 +1,248 @@ +// 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.Runtime.dll", + "CefSharp.Core.dll", + "CefSharp.dll" + }; + + /// + /// List of CefSharp.BrowserSubprocess.exe dependencies. + /// + public static string[] BrowserSubprocessDependencies = + { + "CefSharp.BrowserSubprocess.Core.dll", + "CefSharp.dll", + "icudtl.dat", + "libcef.dll", + //C++/CLI Loader, required by CefSharp.BrowserSubprocess.Core.dll and CefSharp.Core.Runtime.dll + "Ijwhost.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) + { + return CheckDependencies(checkOptional, packLoadingDisabled, path, path, resourcesDirPath, browserSubProcessPath, localePackFile); + } + + /// + /// 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 mangaed dependencies + /// path to check for native (unmanged) 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 managedLibPath, string nativeLibPath, string resourcesDirPath, string browserSubProcessPath, string localePackFile = LocalesPackFile) + { + var missingDependencies = new List(); + + missingDependencies.AddRange(CheckDependencyList(nativeLibPath, CefDependencies)); + + if (!packLoadingDisabled) + { + missingDependencies.AddRange(CheckDependencyList(resourcesDirPath, CefResources)); + } + + if (checkOptional) + { + missingDependencies.AddRange(CheckDependencyList(nativeLibPath, CefOptionalDependencies)); + } + + missingDependencies.AddRange(CheckDependencyList(managedLibPath, 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(nativeLibPath, 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 nativeLibPath; + string managedLibPath = Path.GetDirectoryName(typeof(DependencyChecker).Assembly.Location); + + Uri pathUri; + if (Uri.TryCreate(browserSubProcessPath, UriKind.Absolute, out pathUri) && pathUri.IsAbsoluteUri) + { + nativeLibPath = Path.GetDirectoryName(browserSubProcessPath); + } + else + { + var executingAssembly = Assembly.GetExecutingAssembly(); + + nativeLibPath = Path.GetDirectoryName(executingAssembly.Location); + } + + if (string.IsNullOrEmpty(locale)) + { + locale = "en-US"; + } + + if (string.IsNullOrEmpty(localesDirPath)) + { + localesDirPath = Path.Combine(nativeLibPath, "locales"); + } + + if (string.IsNullOrEmpty(resourcesDirPath)) + { + resourcesDirPath = nativeLibPath; + } + + var missingDependencies = CheckDependencies(true, packLoadingDisabled, managedLibPath, nativeLibPath, 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:" + nativeLibPath); + + throw new Exception(builder.ToString()); + } + } + } +}