查看: 171|回复: 12

使用asp.net core webapi 与 vue 搭建桌面客户端的新尝试

[复制链接]

2

主题

8

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2022-12-5 15:28:24 | 显示全部楼层 |阅读模式
制作桌面程序的技术非常多
Qt,windows Form,WPF,Electron ,flutter 等等

由于制作可视化以及设置表单什么的用前端技术实在是太方便了,用原生拖控件也不是不行,WPF设计模式也真的很帅,但....

奈何一个没有精力维护,一方面还没有点开技能树,另一方面也为了迁就跨平台的能力,所以界面还是希望使用的网页技术制作。

使用大家常说的electron时,发现调用c++code时不是很友好,比较依赖于编译的版本。同时性能也存在一些问题。

作为一个后端,还是打算用自己熟悉的技术栈来实现目标
那到底能否使用http://asp.net core web api 与 vue 静态页 来搭建桌面客户端呢?、
先说结论是可以的,着急的话可以直接看代码
<hr/>原始方案 WPF

要从wpf说起
wpf毕竟是集大成的框架,设计思路领先前端10年(

用wpf也不是不行吧,就是复杂的可视化一多,用wpf自己手写总觉得不太合适,毕竟感觉以后wpf的项目也不多,造个自己的轮子也不划算。

那就干脆只用wpf的webview控件好了,于是有了改进方案一
<hr/>改进方案一 IIS 中 host 前后端站点,与webview配合

思路是在iis中host一个api服务,并在vue编写的前端中调用,最后在webview控件中显示前端页
为什么弄两个站点
官方不是没有`http://asp.net core vue`的模板,但感觉太重了,同时自己前后端分离开发习惯了,一下子弄到一起还有点不习惯,(并且平时前端的静态文件也是分离部署的。
一个小问题
WPF中原生的webview内核是ie,对vue的支持不是很好,会有奇怪的js脚本警告。
查阅资料后发现wpf中可以用 cefsharp一个chromium内核的webview控件替换原始的webview 从而解决这个问题
另一个问题
webview如何与网页通信呢?
cefsharp中其实都提供了通信的方法,它能够实现
1. call a JavaScript method from .NET
2. call a JavaScript method that returns a result
3. expose a .NET class to JavaScript
...



大意就是,可以做。不过我感觉挺麻烦的(其实也不麻烦

但是我在想有没有更简单,或者我更熟悉的方法,来建立webview 和 后端的联系。

另外,两个站点好碍眼啊,能不能合并一下,平时静态文件会部署在cdn服务器上 所以适合分离部署,但在客户端情况下,希望客户执行程序时所需要的依赖越少越好才对。所以有了改进方案二
<hr/>改进方案二 合并vue与webapi站点并自托管

查阅资料后发现,这部分还蛮轻松的。
将前端文件build好后直接拷贝到web api 的wwwroot文件夹中即可
最初还以为宇宙第一IDE 中自带添加wwwroot文件夹的方法,还找了好一阵子。
后来发现wwwroot就只是一个普通文件夹而已,新建一个文件夹然后改名为wwwroot就好啦

在vscode 中 也可以直接新建一个文件夹。但是我发现调试可以,但发布就不行了,看了看输出目录,发现wwwroot根本没有拷贝过来。
查阅资料后,增加下列内容到project节点就好了,表示wwwroot下面的文件直接拷贝过去。



*代表当前路径下的所有同级文件,**表示当前路径下以及所有子文件夹里的文件

并在configure 中添加以下两行



表示响应wwwroot中的静态文件,并且使用其中的index.html等默认文件名去响应请求

PS: 这里的vue使用的hash mode。若是需要使用history mode 需要重写一下响应
好了,事情到了这,以及变成运行两个exe了(一个wpf的webview,一个api与vue的网站),理论上来说在其中一个exe中调用控制台命令开启另一个也不是不行(但就感觉多此一举,最好还是合并到一起吧
在我思考改把哪边并到哪边去时,我发现一个三行代码可运行webviewer的nuget包 webwindow,于是有了改进方案三
<hr/>改进方案三

到了这里,客户端的界面就剩了一个webview。他是不是wpf对于我而言已经不重要了。

刚好看见一个库 webwindow,
按他的文档 新建一个命令行程序,添加以下三行即可运行一个webview的程序



不过需要安装edge beta呢

不使用webview的内置的互相调用方法,前后端进行实时双向通讯
signalr 是一个常用的websocket 库了,vue中支持的非常好,同时http://asp.net core webpai中也可以十分方便的添加。
我们项目的启动流程应该是

1. 启动网站服务
2. 打开webwindows

所以我们将原http://asp.net core program中的



即把阻塞型改为非阻塞型,添加webwindow启动函数


为啥启动的时候还有命令行窗口,如何隐藏?
我们发现启动项目的时候,还会是会启动一个命令行窗口

虽然在 dotnet framework 程序可以简单通过设置OutputType 为 WinExe 解决。如果这时使用跨平台多项目,就会看到 dotnet core 项目依旧会显示黑色窗口

查阅资料发现安装一下NSubsys这个包就好啦

PS 调试的时候还是会显示黑框的,不过直接运行exe就会隐藏命令行呢

这样就几乎使用绝大部分的网站技术,构建了一个独立运行的客户端啦
回复

使用道具 举报

1

主题

5

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2022-12-5 15:28:42 | 显示全部楼层
太厉害了!
回复

使用道具 举报

2

主题

5

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2022-12-5 15:29:36 | 显示全部楼层
利用本文的技术栈 开发的一个桌面小工具 https://zhuanlan.zhihu.com/p/186285539
回复

使用道具 举报

3

主题

10

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2022-12-5 15:30:29 | 显示全部楼层
[赞同]好像有点厉害的样子
回复

使用道具 举报

1

主题

8

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2022-12-5 15:30:51 | 显示全部楼层
哈哈,[捂脸]曲线救国的奇怪操作
回复

使用道具 举报

3

主题

13

帖子

21

积分

新手上路

Rank: 1

积分
21
发表于 2022-12-5 15:31:48 | 显示全部楼层
建议开头上个图
回复

使用道具 举报

2

主题

8

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2022-12-5 15:32:48 | 显示全部楼层
啊 [赞同]谢谢建议 下篇文章会注意的
回复

使用道具 举报

4

主题

10

帖子

20

积分

新手上路

Rank: 1

积分
20
发表于 2022-12-5 15:33:21 | 显示全部楼层
这个方案我已经用了很久了[捂脸][捂脸]
回复

使用道具 举报

3

主题

7

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2022-12-5 15:34:15 | 显示全部楼层
还可以奥 就是这种方案想调用原生桌面文件选择对话框特别绕..还有一些Api不太方便 现在还是回到electron+api的组合了了[捂脸]
回复

使用道具 举报

1

主题

4

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2022-12-5 15:34:57 | 显示全部楼层
你好 能否开发这个方案的源代码 我想看看 谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表