C#想要实现Electron那样混合桌面程序可以用以下几个库.
本文使用EdgeSharp

开始

EdgeSharp可以直接使用HTML,

也可以配合Blazor、Razor 、SolidJs、Svelte、React、Vue、Angular等前端框架。

直接调用系统中Edge浏览器所配套的 WebView2,

无需像Electron那样打包整个浏览器内核,打包后的文件非常小。

更多强大的功能可以查看官方示例,本文只使用了最简单的HTML

EdgeSharp.Samples/angular-react-vue

EdgeSharp.Samples/winform

EdgeSharp.Samples/wpf

创建一个Winform程序

创建后,删除其他文件,只保留 Program.cs

Nuget安装相关依赖

    <PackageReference Include="EdgeSharp.Core" Version="0.9.0" />
<PackageReference Include="EdgeSharp.WinForms" Version="0.9.0" />

将下面代码放入Program.cs中

using System.ComponentModel;
using System.Windows.Forms; using EdgeSharp.Core;
using EdgeSharp.Core.Configuration;
using EdgeSharp.Core.Defaults;
using EdgeSharp.Core.Infrastructure;
using EdgeSharp.WinForms; using HelloEdgeSharp.Controller; using Microsoft.Extensions.DependencyInjection; namespace HelloEdgeSharp
{
internal static class Program
{ [STAThread]
static void Main()
{
try
{
Application.SetHighDpiMode(System.Windows.Forms.HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); var appBuilder = new AppBuilder<Startup>();
ServiceLocator.Bootstrap(appBuilder);
var bowserForm = (BrowserForm)ServiceLocator.Current.GetInstance<IBrowserWindow>();
Application.Run(bowserForm);
appBuilder?.Stop();
}
catch (Exception e)
{ MessageBox.Show(e.Message);
} }
} public class Startup : WinFormsStartup
{
public override void ConfigureServices(IServiceCollection services)
{
base.ConfigureServices(services); services.AddSingleton<IConfiguration, SampleConfig>(); services.AddSingleton<IBrowserWindow, SampleBrowserForm>(); // 注入 控制器
RegisterActionControllerAssembly(services, typeof(HelloController).Assembly);
} public override void Initialize(IServiceProvider serviceProvider)
{
base.Initialize(serviceProvider);
}
} internal class SampleConfig : Configuration
{
public SampleConfig() : base()
{
// 拦截 api 并导航到 Controller (用RegisterActionControllerAssembly注册控制器)
UrlSchemes.Add(new("http", "api", null, UrlSchemeType.ResourceRequest));
// 静态文件资源 拦截 导航到 wwwroot
UrlSchemes.Add(new("http", "app", "wwwroot", UrlSchemeType.HostToFolder)); // 设置 首页地址
StartUrl = "http://app/index.html"; ; // 去掉窗口标题栏
//WindowOptions.Borderless = true; }
} internal class SampleBrowserForm : BrowserForm
{ public SampleBrowserForm()
{
Width = 1200;
Height = 900; var executable = System.Reflection.Assembly.GetExecutingAssembly();
var iconStream = executable.GetManifestResourceStream("EdgeSharp.WinForms.Sample.edgesharp.ico");
if (iconStream != null)
{
Icon = new Icon(iconStream);
}
} // 可以重写 各种生命周期
protected override void Bootstrap()
{
base.Bootstrap();
} protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
}
}
}

新建 Controller/HelloController.cs

继承 ActionController , 并添加 ActionController , ActionRoute 两个特性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using EdgeSharp.Core.Network; namespace HelloEdgeSharp.Controller
{
[ActionController(Name = "HelloController", Description = "测试控制器")]
public class HelloController : ActionController
{ public class UserInfo
{
public int Id { get; set; }
public string Name { get; set; }
public string Version { get; set; }
public string Url { get; set; }
}
public class Result<T>
{
public bool Succeeded { get; set; } public T Data { get; set; }
public string Errors { get; set; }
} [ActionRoute(Path = "/getFrameWorks")]
public Result<object> GetFrameWorks(int index, int size)
{
var list = new List<UserInfo>
{
new UserInfo()
{
Id = 1, Name = "React",
Version = "v1",
Url = "http://www.react.com",
},
new UserInfo()
{
Id = 2,
Name = "Vue",
Version="v2",
Url = "http://www.vue.com",
}
}; return new Result<object>
{
Succeeded = true,
Data = new
{
Items = list,
TotalCount = 100,
}
};
} }
}

新建 wwwroot/index.html

html代码省略
这里是Js发起请求与C#交互的关键代码

// 在C# SampleConfig 中配置了UrlSchemeType.ResourceRequest,
// 会拦截这个域名 http://api/ 的请求
let instance = axios.create({
baseURL: "http://api/",
timeout: 15000,
});
// 发起get请求
instance.get("/getFrameWorks?index=1&size=2")
.then(r => {
// 成功拿到controller中返回的数据
console.log(r)
})

运行项目

这样我们就得到了一个使用HTML作为页面,C#作为后端的桌面程序

Github地址

全部源码

C#使用WebView2替代Electron的更多相关文章

  1. 微软要放弃Electron了???聊聊WebView2

    有好几个公众号发文说"微软要放弃Electron了",实际情况是微软旗下的Teams产品打算把Electron框架换成WebView2而已.接下来我就聊一下这个事情: 微软不会放弃 ...

  2. 放弃 Electron,拥抱 WebView2!JavaScript 快速开发独立 EXE 程序

    Electron 不错,但也不是完美的. Electron 带来了很多优秀的桌面软件,但并不一定总是适合我们的需求. 多个选择总是好事! 我使用 Electron 遇到的一些麻烦 1.Electron ...

  3. 使用 AngularJS 和 Electron 构建桌面应用

    GitHub 的 Electron 框架(以前叫做 Atom Shell)允许你使用 HTML, CSS 和 JavaScript 编写跨平台的桌面应用.它是io.js 运行时的衍生,专注于桌面应用而 ...

  4. Electron开发环境部署

    Electron开发环境部署 安装node.js 可以从node.js官方网站上获取安装包,并进行安装,安装完可以通过 ndoe -v 指令进行版本查看. 本文的开发环境为node.js 4.4.5. ...

  5. AngularJS 和 Electron 构建桌面应用

    译]使用 AngularJS 和 Electron 构建桌面应用 原文: Creating Desktop Applications With AngularJS and GitHub Electro ...

  6. Electron与jQuery中$符号冲突的三种解决方法

    在Electron工程中引用jQuery时,经常会出现以下错误: Uncaught ReferenceError: $ is not defined 解决的具体方法如下: ①.在测试的过程中(测试过1 ...

  7. 第二章 你第首个Electron应用 | Electron in Action(中译)

    本章主要内容 构建并启动Electron应用 生成package.json,配置成Electron应用 在你的项目中包含预先构建Electron版本 配置package.json以启动主进程 从主进程 ...

  8. 从零开始学Electron笔记(五)

    在之前的文章我们介绍了一下Electron的右键菜单的制作,接下来我们继续说一下Electron如何通过链接打开浏览器和嵌入网页. 现在有这样一个需求,我们要在我们的软件中加一个链接,然后点击该链接打 ...

  9. Electron入门指北

    最近几年最火的桌面化技术,无疑是Qt+和Electron. 两者都有跨平台桌面化技术,并不局限于Windows系统.前者因嵌入式而诞生,在演变过程中,逐步完善了生态以及工具链.后者则是依托于Node. ...

  10. 基于vue3.0+electron新开窗口|Electron多开窗体|父子模态窗口

    最近一直在折腾Vue3+Electron技术结合的实践,今天就来分享一些vue3.x和electron实现开启多窗口功能. 开始本文之前,先来介绍下如何使用vue3和electron来快速搭建项目. ...

随机推荐

  1. docker 应用篇————docker 的文件系统[十]

    前言 简单介绍一下docker的文件系统. 正文 docker 容器启动就是一个文件系统的启动. 在docker中,每一层镜像都具备一些文件. 比如说,有一个centos的镜像. 里面就是一个微小版的 ...

  2. mysql 重新整理——配置文件[一]

    前言 对mysql 进行从新整理一下,仅做参考,如有任何不对望指出. 正文 mysql 一般分windows和linux,但是他们的运行配置其实是一样的,所以在此不做区分. 直接上一个大体的图: 我个 ...

  3. WebRTC获取IP地址问题,Uncaught TypeError: Cannot read property '1' of null

    WebRTC获取IP地址问题,Uncaught TypeError: Cannot read property '1' of null 临时接了个任务,客户要求某个账号只能在某个ip或者mac上登录, ...

  4. 力扣665(java)-非递减数列(中等)

    题目: 给你一个长度为 n 的整数数组 nums ,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列. 我们是这样定义一个非递减数列的: 对于数组中任意的 i (0 <= ...

  5. Go原生插件使用问题全解析

    简介: 本人在设计和落地基于Go原生插件机制的扩展开发产品时踩到了很多坑,由于这方面相关资料很少,因而借此机会做一个非常粗浅的总结,希望能对大家有所帮助.本文只说问题和解决方案,不读代码. 作者 | ...

  6. 阿里云容器服务全面升级为 ACK Anywhere,让云的边界拓展至企业需要的每个场景

    ​简介: 2021 年 9 月 26 日上海阿里云计算峰会上,阿里巴巴研究员.阿里云云原生应用平台负责人丁宇宣布,阿里云容器服务全面升级为 ACK Anywhere,让企业在任何需要云的地方,都能获得 ...

  7. TSDB时序数据库时序数据压缩解压技术浅析

    ​简介: 目前,物联网.工业互联网.车联网等智能互联技术在各个行业场景下快速普及应用,导致联网传感器.智能设备数量急剧增加,随之而来的海量时序监控数据存储.处理问题,也为时序数据库高效压缩.存储数据能 ...

  8. [GPT] 对于一个复杂的html文档而言,如何用 js 批量替换页面上的某些文字从A替换为B,前提是不能去掉标签和已绑定的事件

      原生:示例代码 function replaceTextInDocument(node) { if (node.nodeType === Node.TEXT_NODE) { node.textCo ...

  9. [Go] golang 时间格式化 12小时制 与 24小时制

    timestamp := int64(1591271169) # 12小时制 time.Unix(timestamp, 0).Format("2006-01-02 03:04:05" ...

  10. UWP 写入图片 Exif 信息

    本文告诉大家如何在 UWP 中,保存图片的时候,写入 Exif 信息,也就是如照片的 相机型号 制造商 光圈值等信息的写入 在 UWP 中,保存图片或照片需要用到图片编码器,在使用编码器写入前可以设置 ...