• C#使用WebView2替代Electron


    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地址

    全部源码
  • 相关阅读:
    Windows下 如何添加开机启动项
    Android在 普通类(非Activity,多数为Adapter) 中 传输数据为空值 解决方法 :在startActivity 用 intent传输数据
    Android 从ImageView中获取Bitmap对象方法
    剑指offer(纪念版)读书笔记【实时更新】
    剑指offer(纪念版) 面试题3:二维数组中的查找
    C++ sizeof 误区 大公司面试题
    51 nod 1521 一维战舰 时间复杂度O(n),同 Codeforces 567D. One-Dimensional Battle Ships 有详细注释
    51nod 1126 求递推序列的第N项 思路:递推模拟,求循环节。详细注释
    51nod 1451 合法三角形 判斜率去重,时间复杂度O(n^2)
    关于JetBrains CLion 激活 (CLion License Activation)的解决办法,带hosts详细修改
  • 原文地址:https://www.cnblogs.com/webenh/p/16055827.html
Copyright © 2020-2023  润新知