[Asp.Net Core] Blazor Server Side 擴展用途 - 配合CEF來製作客戶端瀏覽器軟體

来源:https://www.cnblogs.com/zhgangxuan/archive/2020/04/28/blazor_server_side_cef_browser_01.html
-Advertisement-
Play Games

是否能編譯一個exe , 又能啟動 Asp.Net Core , 又能自帶最新版的Chromium瀏覽器 , 自己瀏覽自己? 這裡給出了一個最簡單的C#/C++整合CEF框架的方式和詳細步驟. ...


前言

大家用過微信PC端吧? 這是用瀏覽器做的. 

用過Visual Studio Code吧? 也是用瀏覽器做的. 

聽說, 暴雪客戶端也包含瀏覽器核心?? 

在客戶端啟動一個瀏覽器, 並不是什麼難事了. 

 

現在既然用開了Blazor server side技術 , 

那麼當然是也想用Blazor server side來做客戶端軟體了. 

沒錯, 的確是Blazor server side技術. 客戶端也可以使用這技術的. 

 

雖然現在有很多各種各樣用於 DotNet 的 CEF 框架, 但是大部分還沒有一步到位.

這次要做的是, 打算弄一個開源項目, 做成 DotNet 的 dll , 生成項目模板, 讓開發者直接用上. 

(本教程包含 C++部分, 但後續的開源項目, 會去掉C++部分, 只剩下一個CppInterop.dll 和項目模板)

 

開發者難度:

    當這個模板做好之後, 對於初步用途來說, 沒有難度. 開發者可以直接複製模板, 然後在模板上加入自己的代碼便可. 

    和一般的CEF C#框架不一樣, 這邊不是針對瀏覽器技術, 而是針對開發者最常用的幾個功能去考慮, 直接做好簡單易用的API 

 

目標與好處

  1. 開發者下載到項目模板之後, 用VS2019打開, 直接編譯直接運行. 不要再搞那些複雜的玩意了. 
  2. 在用戶的電腦上運行 Asp.Net Core 網站, 並且自啟瀏覽器去顯示. 
  3. 又或者, 向客戶提供一個特殊的瀏覽器, 滿足網站的擴展許可權功能. 
  4. 開發者可以像做網站一樣做客戶端程式. 
  5. 不限定 Blazor , 可以是 Mvc, 甚至是ReactJS/ArgularJS/VueJS/jQuery等都OK的. 
  6. 能保證瀏覽器的版本, 不用考慮瀏覽器相容性問題
  7. Asp.Net Core在客戶端運行, 擁有客戶端PC的許可權, 可以隨意操作用戶電腦的文檔, 
  8. 方便地與客戶端的各種程式進行操作, 例如按需啟動客戶端程式編輯內容, 編輯完再繼續處理.
  9. 鍵盤給大家, 大家自己寫...

概念思考

  1. 由於是客戶端程式, 所以所有的資源已經打包好了. 除非要訪問伺服器進行交互下載, 否則正常的功能是無延遲無網路中斷問題的. 
  2. 理論上整合了C++的部分, 是可以整合各種C++玩意, 例如把ActiveX整合進程式的.(非整合進瀏覽器)
  3. .....

 


 

以下整合步驟只給有C++經驗的人士觀看.  其他人等這個項目的成品出來便可. 

整合步驟 

CEF項目地址 : https://github.com/chromiumembedded/cef

CEF下載地址 http://opensource.spotify.com/cefbuilds/index.html , 找到 Windows 32位的版本, 這樣可以相容性更好

 

 下載後, 解壓到更短的路徑, 因為後面要使用 . 

         

 

 進入 https://cmake.org/ , 下載 : CMake , 然後運行, 輸入目錄, 與輸出目錄(生成 VS2019 Solution).

 

 配置:

 

 

 

 提示有錯嗎? 不管. 直接點多一次 Generate 便可. 


 

註意, VISUAL STUDIO 2019 必須安裝 C++ 和 C++ CLI 

打開工程, 配置編譯.   我們只需編譯這些玩意:  (或者把那幾個不用的工程刪掉算了)

 

 先編譯一次, 應該會通過.  

 

 

在下載的文件裡面, 找到這4個文件 , C++不好寫, 但是我們可以在樣板工程上直接改. 

 複製到 libcef_dll_wrapper 工程目錄下, 並且添加現有項 : 

 

 

 修改 simple_app.cc  , 在16行插入

std::string _surl;
std::string GetStartupUrl()
{
    return _surl;
}


void SetStartupUrl(LPTSTR url)
{
    char chars[2048];
    int cch = WideCharToMultiByte(936, 0, url, -1, 0, 0, NULL, NULL);
    WideCharToMultiByte(936, 0, url, -1, chars, cch, NULL, NULL);
    _surl = chars;
}

int RunCefApp(LPTSTR cmdline)
{
    HINSTANCE hinst = (HINSTANCE)GetModuleHandle(NULL);
    wWinMain(hinst, NULL, cmdline, 0);
    return 0;
}

找到 command_line->GetSwitchValue("url") 這一行, 把啟動Url 換掉 , 這樣後面 SetUrl 就有效果啦.

 

編譯, 通過. 

 

 CppInterop工程

 

 新增一個C++ CLI工程 (註意, CLI沒打錯字, CLI和CLR概念不一樣, 請自行搜索)

 

 項目名稱 CppInterop 好了. 

 添加引用

 

 

添加 libcef.lib ,  Debug的用  cef32\Debug\libcef.lib ,  Release的用  cef32\Release\libcef.lib

 

修改 CppInterop.cpp

#include "pch.h"

#include <Windows.h>

using namespace System;

void SetStartupUrl(LPTSTR url);
int RunCefApp(LPTSTR cmdline);

WCHAR cscmd[4096];
WCHAR csurl[4096];

namespace CppInterop {
    public ref class Cpp
    {
    public:
        static void SetUrl(String^ url)
        {
            for (int i = 0; i < url->Length; i++)
                csurl[i] = url[i];
            csurl[url->Length] = '\0';

            SetStartupUrl(csurl);
        }
        static int Run(String^ cmdline)
        {
            for (int i = 0; i < cmdline->Length; i++)
                cscmd[i] = cmdline[i];
            cscmd[cmdline->Length] = '\0';

            return RunCefApp(cscmd);

        }
    };
}

 

 

編譯 CppInterop工程.  通過. 

自此, C++部分已經完結. 


 

BlazorApp1

新建dotnetcore Blazor Server 工程 ,  添加對 CppInterop 的引用, 

無論是 Debug或Release , 都修改為 x86架構

 

程式入口改為:

        [STAThread]
        public static void Main(string[] args)
        {
            string cmdargs = string.Join(" ", args);

            if (cmdargs.Contains("--type="))
            {
                CppInterop.Cpp.Run(cmdargs);
                return;
            }

            System.Threading.CancellationTokenSource cts = new System.Threading.CancellationTokenSource();
            var tsk = CreateHostBuilder(args).Build().RunAsync(cts.Token);
            CppInterop.Cpp.SetUrl("https://localhost:5001");
            CppInterop.Cpp.Run(cmdargs);
            cts.Cancel();
            tsk.Wait(3000);
        }

 

 

不要用IIS啟動了, 必須用exe方式啟動:

 

 

 把 D:\Temp\cef32\Resources 和 D:\Temp\cef32\Debug  複製到輸出文件夾 

 

 啟動項目: 

 

 

Edge瀏覽器正常,  但是自己啟動的瀏覽器無法啟動子進程渲染器,  原因是 COM thread model 有問題. 估計是Debug模式的問題. 

解決方法有兩種,   一種是使用參數 --single-process 啟動 :

 

 

 

 這種模式好啊.  只有1個進程. 

 

另外一種模式是 , 編譯為Release 再執行 : 

 

 

 去掉 --single-process的效果:

 

 這個和一般的瀏覽器的行為一致了. 

 

顯示控制台, 有助於查看調試信息. 

如果不想控制台彈出來, 可以把工程的屬性改掉. 從 '控制台應用程式' 改成 'Windows應用程式'

 


 

結尾

目前先記錄到這裡. 

後面還有一大堆要和瀏覽器進行交互的事情. 

對於開發者來說, 目前考慮有以下需求需要解決:

1 - C# 代碼能控制視窗的大小 , 最大化, 最小化等等.  例如啟動時固定大小, 登錄後, 自動最大化. 

2 - C# 代碼可以自己實現一些下載的功能,  

3 - 可以自定義方式彈出DevTools,

4 - 如何另外彈出WinForms, WPF界面. 

5 - 如何與真正的伺服器進行通信, 如何下載伺服器的dll執行. 

...

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、代碼實現 1.數組轉換成List String[] deviceIdAy = buildingDto.getChannelId().split(Symbol.COMMA);//設備idList<String> deviceIdList = Arrays.asList(deviceIdAy); 2 ...
  • 目錄 pyecharts模塊 簡介 Echarts 是一個由百度開源的數據可視化,憑藉著良好的交互性,精巧的圖表設計,得到了眾多開發者的認可。而 Python 是一門富有表達力的語言,很適合用於數據處理。當數據分析遇上數據可視化時,pyecharts 誕生了。 如果想要掌握pyecharts,可以閱 ...
  • 最近在項目中遇到一個需要用線程池來處理任務的需求,於是我用 來實現,但是在實現過程中我發現提交大量任務時它的處理邏輯是這樣的(提交任務還有一個 方法內部也調用了 方法): java public void execute(Runnable command) { if (command == null ...
  • 堆記憶體常見的分配策略 針對的是Serial 加 Serial Old 客戶端預設收集器組合下的記憶體分配和回收策略 經典的垃圾收集器 CMS 收集器 CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的垃圾收集器。從名字可以看出,CMS 是基於標記-清除演算法的 ...
  • 隨著PHP7.4而來的有一個我認為非常有用的一個擴展:PHP FFI(Foreign Function interface),引用一段PHP FFI RFC中的一段描述 For PHP, FFI opens a way to write PHP extensions and bindings to ...
  • 搬運自:https://www.cnblogs.com/AlanLee/p/5329555.html 原理搜關鍵字:DFA演算法 基本照抄了原文的JAVA代碼,其中應該可以用Dictionary<string,int>來代替Hashtable,但搜到的資料都說Hashtable快得要命,雖然知道他們說 ...
  • 前言 CQRS ( Command Query Responsibility Segregation )命令查詢職責分離模式,它主要從我們業務系統中進行分離出我們(Command 增、刪、改)和(Query 查), 同時他可以明確的區分我們每一個動作向我們的請求模型和響應模型.從而降低了我們系統的復 ...
  • [TOC] 上一篇,我們學習了任務的基礎,學會多種方式場景任務和執行,非同步獲取返回結果等。上一篇講述的知識比較多,這一篇只要是代碼實踐和示例操作。 判斷任務狀態 | 屬性 | 說明 | | | | | IsCanceled | 獲取此 Task 實例是否由於被取消的原因而已完成執行。 | | IsC ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...