[Asp.Net Core] Blazor Server Side 扩展用途 – 配合CEF来制作客户端浏览器软件
- 2020 年 4 月 28 日
- 筆記
- Asp.Net, Blazor, Blazor Server Side, CEF
前言
大家用过微信PC端吧? 这是用浏览器做的.
用过Visual Studio Code吧? 也是用浏览器做的.
听说, 暴雪客户端也包含浏览器核心??
在客户端启动一个浏览器, 并不是什么难事了.
现在既然用开了Blazor server side技术 ,
那么当然是也想用Blazor server side来做客户端软件了.
没错, 的确是Blazor server side技术. 客户端也可以使用这技术的.
虽然现在有很多各种各样用于 DotNet 的 CEF 框架, 但是大部分还没有一步到位.
这次要做的是, 打算弄一个开源项目, 做成 DotNet 的 dll , 生成项目模板, 让开发者直接用上.
(本教程包含 C++部分, 但后续的开源项目, 会去掉C++部分, 只剩下一个CppInterop.dll 和项目模板)
开发者难度:
当这个模板做好之后, 对于初步用途来说, 没有难度. 开发者可以直接复制模板, 然后在模板上加入自己的代码便可.
和一般的CEF C#框架不一样, 这边不是针对浏览器技术, 而是针对开发者最常用的几个功能去考虑, 直接做好简单易用的借口.
目标与好处
- 在用户的电脑上运行 Asp.Net Core 网站, 并且自启浏览器去显示.
- 又或者, 向客户提供一个特殊的浏览器, 满足网站的扩展权限功能.
- 开发者可以像做网站一样做客户端程序.
- 不限定 Blazor , 可以是 Mvc, 甚至是ReactJS/ArgularJS/VueJS/jQuery等都OK的.
- 能保证浏览器的版本, 不用考虑浏览器兼容性问题
- Asp.Net Core在客户端运行, 拥有客户端PC的权限, 可以随意操作用户电脑的文档,
- 方便地与客户端的各种程序进行操作, 例如按需启动客户端程序编辑内容, 编辑完再继续处理.
- 键盘给大家, 大家自己写…
概念思考
- 由于是客户端程序, 所以所有的资源已经打包好了. 除非要访问服务器进行交互下载, 否则正常的功能是无延迟无网络中断问题的.
- 理论上整合了C++的部分, 是可以整合各种C++玩意, 例如把ActiveX整合进程序的.(非整合进浏览器)
- …..
以下整合步骤只给有C++经验的人士观看. 其他人等这个项目的成品出来便可.
整合步骤
CEF项目地址 : //github.com/chromiumembedded/cef
CEF下载地址 //opensource.spotify.com/cefbuilds/index.html , 找到 Windows 32位的版本, 这样可以兼容性更好
下载后, 解压到更短的路径, 因为后面要使用 .
进入 //cmake.org/ , 下载 : CMake , 然后运行, 输入目录, 与输出目录(生成 VS2019 Solution).
配置:
提示有错吗? 不管. 直接点多一次 Generate 便可.
注意, VISUAL STUDIO 2019 必须安装 C++ 和 C++ CLI
打开工程, 配置编译. 我们只需编译这些玩意: (或者把那几个不用的工程删掉算了)
先编译一次, 应该会通过.
在下载的文件里面, 找到这4个文件 , C++不好写, 但是我们可以在样板工程上直接改.
复制到 libcef_dll_wrapper 工程目录下, 并且添加现有项 :
修改 cefsimple_win.cc , 21行插入
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架构
不要用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执行.
…