为 CefSharp 应用内置 C++ 运行环境并启用 AnyCPU 支持
一個 CefSharp 應(yīng)用程序要想正確運行,有兩個必要條件:
.NET Framework 4.5.2
VC++ 2015
在部署 CefSharp 應(yīng)用時經(jīng)常會遇到因為沒有 VC++ 2015 而無法運行的問題:
通過事件查看器,可以觀察到一個類型為:System.IO.FileNotFoundException 的異常。
檢測 VC++ 2015 運行環(huán)境是否安裝。
我們可以使用以下 C# 代碼來檢測本機上是否已經(jīng)部署了 VC++ 2015 運行環(huán)境:
public static bool IsVc2015Installed(){var dependenciesPath = @"SOFTWARE\Classes\Installer\Dependencies";var plat = Environment.Is64BitProcess ? "x64" : "x86";using (var dependencies = Registry.LocalMachine.OpenSubKey(dependenciesPath)){if (dependencies == null){return false;}foreach (var subKeyName in dependencies.GetSubKeyNames().Where(n =>!n.ToLower().Contains("dotnet") && !n.ToLower().Contains("microsoft"))){using (var subDir = Registry.LocalMachine.OpenSubKey(dependenciesPath + "\\" + subKeyName)){if (subDir == null){continue;}var value = subDir.GetValue("DisplayName")?.ToString() ?? null;if (string.IsNullOrEmpty(value)){continue;}if (Regex.IsMatch(value, $@"C\+\+ 2015.*\({plat}\)")) //here u can specify your version.{return true;}}}}return false;}內(nèi)置 VC++ 2015 運行時文件
VC++ 2015 運行環(huán)境是可以通過 XCopy 部署的。即:如果我們的程序需要 VC++ 2015 運行環(huán)境,僅需將 VC++ 2015 的全部文件復(fù)制到應(yīng)用程序目錄即可。事實上,有很多商業(yè)軟件也是這么做的,比如:Navicat 。應(yīng)用程序目錄下一系列 “api-ms-win” 開頭的 DLL 文件就是運行時文件。
當我們的 CefSharp 的目標平臺僅為 x86 或 x64 ,內(nèi)置 VC++ 2015 運行時僅需將對應(yīng)的文件復(fù)制到輸出目錄即可。
如果要啟用 AnyCPU 支持,我們?nèi)孕铻橹鞒绦蜓b載 VC++ 2015 運行時。
啟用 AnyCPU 支持
以上一篇?讓 CefSharp.WinForms 應(yīng)用程序同時支持32位(x86)和64位(x64)的解決方案?的代碼為模板,在 Program 文件中增加?_dllLoaded?變量來保存 VC++ 2015 環(huán)境是否已經(jīng)具備。在 Program 類型的靜態(tài)構(gòu)造函數(shù)中調(diào)用?IsVc2015Installed?函數(shù)來確認是否已經(jīng)安裝了 VC++ 2015 環(huán)境,并將結(jié)果賦值給?_dllLoaded?變量。這代表著,如果本機已經(jīng)安裝過 VC++ 2015 運行環(huán)境,則程序內(nèi)置的環(huán)境將不會被加載。
可以使用以下 Windows API 加載非托管類庫:
[DllImport("kernel32.dll")]private static extern IntPtr LoadLibrary(string lpFileName);聲明靜態(tài)的只讀字符串數(shù)組變量?DllList?用于保存 VC++ 2015 的全部文件名:
private static readonly string[] DllList ={"api-ms-win-core-console-l1-1-0.dll", "api-ms-win-core-datetime-l1-1-0.dll","api-ms-win-core-debug-l1-1-0.dll", "api-ms-win-core-errorhandling-l1-1-0.dll","api-ms-win-core-file-l1-1-0.dll", "api-ms-win-core-file-l1-2-0.dll","api-ms-win-core-file-l2-1-0.dll", "api-ms-win-core-handle-l1-1-0.dll","api-ms-win-core-heap-l1-1-0.dll", "api-ms-win-core-interlocked-l1-1-0.dll","api-ms-win-core-libraryloader-l1-1-0.dll", "api-ms-win-core-localization-l1-2-0.dll","api-ms-win-core-memory-l1-1-0.dll", "api-ms-win-core-namedpipe-l1-1-0.dll","api-ms-win-core-processenvironment-l1-1-0.dll", "api-ms-win-core-processthreads-l1-1-0.dll","api-ms-win-core-processthreads-l1-1-1.dll", "api-ms-win-core-profile-l1-1-0.dll","api-ms-win-core-rtlsupport-l1-1-0.dll", "api-ms-win-core-string-l1-1-0.dll","api-ms-win-core-synch-l1-1-0.dll", "api-ms-win-core-synch-l1-2-0.dll","api-ms-win-core-sysinfo-l1-1-0.dll", "api-ms-win-core-timezone-l1-1-0.dll","api-ms-win-core-util-l1-1-0.dll", "api-ms-win-crt-conio-l1-1-0.dll","api-ms-win-crt-convert-l1-1-0.dll", "api-ms-win-crt-environment-l1-1-0.dll","api-ms-win-crt-filesystem-l1-1-0.dll", "api-ms-win-crt-heap-l1-1-0.dll","api-ms-win-crt-locale-l1-1-0.dll", "api-ms-win-crt-math-l1-1-0.dll","api-ms-win-crt-multibyte-l1-1-0.dll", "api-ms-win-crt-private-l1-1-0.dll","api-ms-win-crt-process-l1-1-0.dll", "api-ms-win-crt-runtime-l1-1-0.dll","api-ms-win-crt-stdio-l1-1-0.dll", "api-ms-win-crt-string-l1-1-0.dll","api-ms-win-crt-time-l1-1-0.dll", "api-ms-win-crt-utility-l1-1-0.dll","ucrtbase.dll"};新增?CheckDll?方法,根據(jù)運行環(huán)境加載對應(yīng)的 VC++ 2015 運行時:
private static void CheckDll() // 檢查瀏覽器的DLL是否載入{if (_dllLoaded){return;}var dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Environment.Is64BitProcess ? "x64" : "x86");foreach (var fname in DllList){try{var path = Path.Combine(dir, fname);if (File.Exists(path)){LoadLibrary(path);}}catch{}}_dllLoaded = true;}注意:CheckDll 需要在 Resolver 方法中被調(diào)用。完成以上操作后,CefSharp程序就可以在未安裝 VC++ 2015 環(huán)境的機器上成功運行了:
開源
本文所展示的全部代碼和項目工程均在 Gitee 上開源。完整的項目文件和依賴文件可以在以下地址拿到:
https://gitee.com/coderbusy/demo/tree/master/WinForm/CefSharpEmbedCppRunTime
總結(jié)
以上是生活随笔為你收集整理的为 CefSharp 应用内置 C++ 运行环境并启用 AnyCPU 支持的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET 云原生架构师训练营(模块二 基
- 下一篇: IOT必备之MQTT结构分析,不进来看看