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

本文使用EdgeSharp

NanUI

Photino

Electron.NET

EdgeSharp

Chromely

开始

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#作为后端的桌面程序

最后修改于 2022-01-03 21:53:41
上一篇