为 CefSharp 应用内置 C++ 运行环境并启用 AnyCPU 支持
一個 CefSharp 應用程序要想正確運行,有兩個必要條件:
.NET Framework 4.5.2
VC++ 2015
在部署 CefSharp 應用時經常會遇到因為沒有 VC++ 2015 而無法運行的問題:
通過事件查看器,可以觀察到一個類型為:System.IO.FileNotFoundException 的異常。
檢測 VC++ 2015 運行環境是否安裝。
我們可以使用以下 C# 代碼來檢測本機上是否已經部署了 VC++ 2015 運行環境:
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;}內置 VC++ 2015 運行時文件
VC++ 2015 運行環境是可以通過 XCopy 部署的。即:如果我們的程序需要 VC++ 2015 運行環境,僅需將 VC++ 2015 的全部文件復制到應用程序目錄即可。事實上,有很多商業軟件也是這么做的,比如:Navicat 。應用程序目錄下一系列 “api-ms-win” 開頭的 DLL 文件就是運行時文件。
當我們的 CefSharp 的目標平臺僅為 x86 或 x64 ,內置 VC++ 2015 運行時僅需將對應的文件復制到輸出目錄即可。
如果要啟用 AnyCPU 支持,我們仍需為主程序裝載 VC++ 2015 運行時。
啟用 AnyCPU 支持
以上一篇?讓 CefSharp.WinForms 應用程序同時支持32位(x86)和64位(x64)的解決方案?的代碼為模板,在 Program 文件中增加?_dllLoaded?變量來保存 VC++ 2015 環境是否已經具備。在 Program 類型的靜態構造函數中調用?IsVc2015Installed?函數來確認是否已經安裝了 VC++ 2015 環境,并將結果賦值給?_dllLoaded?變量。這代表著,如果本機已經安裝過 VC++ 2015 運行環境,則程序內置的環境將不會被加載。
可以使用以下 Windows API 加載非托管類庫:
[DllImport("kernel32.dll")]private static extern IntPtr LoadLibrary(string lpFileName);聲明靜態的只讀字符串數組變量?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?方法,根據運行環境加載對應的 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 方法中被調用。完成以上操作后,CefSharp程序就可以在未安裝 VC++ 2015 環境的機器上成功運行了:
開源
本文所展示的全部代碼和項目工程均在 Gitee 上開源。完整的項目文件和依賴文件可以在以下地址拿到:
https://gitee.com/coderbusy/demo/tree/master/WinForm/CefSharpEmbedCppRunTime
總結
以上是生活随笔為你收集整理的为 CefSharp 应用内置 C++ 运行环境并启用 AnyCPU 支持的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: .NET 云原生架构师训练营(模块二 基
- 下一篇: 如何在 ASP.NET Core 中使用
