// 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());
}
}
}
}