虽然工作开发语言已经转到了java,但平时仍会用netcore做一些小工具,提升工作效率,但是笔记本换成了Mac,小工具只能做成命令行形式,很是痛苦,迫切需要一个.net跨平台的桌面程序解决方案。
为什么选择Avalonia
据我所知目前有几个.net跨平台桌面解决方案,如 Electron.NET、Xamarin、Eto.Forms和Avalonia,并对这几个框架进行了一定的尝试。
Electron.NET使用Electron作为前端展示,NetCore作为后台服务,前端可以把一些耗时操作提交给后端处理,但是打包后的程序在OSX启动,每次都会弹出要开启xxxx端口,相对来说不够友好,况且我对js和css比较无感,windows桌面开发经验无法得到利用。
Xamarin新版已经统一了android和ios的代码,除了极少用到各平台特定功能,基本上可以同一套代码编译出两个不同平台版本的程序包,但桌面端还无法使用同一套代码编译进行多平台编译。
Eto.Forms 采用了原生控件映射的方式,可以实现一套代码编译出OSX/Linux/Windows三个平台的程序,采用mono运行时,但现在vs插件只有vs2017的,没有vs2019
Avalonia 采用基于了WPF Xaml,对于有WPF/UWP/Xamarin.Forms开发经验的人来说,极易入手,虽然目前仍处在测试阶段(几年前就这么说了),但已经可以使用该框架编写应用程序,最大的优点是, 程序采用了.NetCore 运行时,所以使用dotnet publish跨平台发布,就可以在单平台下编译出适合多个平台的应用程序。
开发准备
1 对于使用Visual Studio 2017/2019的人来说,可以直接通过VS的Marketplace安装Avalonia扩展,或者直接通过 此链接 下载后安装(此扩展不支持Visual Studio for Mac)
2 对于没有Visual Studio或者在非Windows平台上开发的人来说,可以使用.NetCore CLI安装Avalonia项目模板
a) 克隆项目模板库到本地
git clone https://github.com/AvaloniaUI/avalonia-dotnet-templates.git
b) 安装模板库
dotnet new -i [模板库存放的本地路径]
安装完成后可以看到
创建Avalonia项目程序
接下来以Visual Studio 2019
虽然第二步选择了 .NetFramework 4.7.2版本,但是目标框架仍是 .NetCoreApp2.1和NetFramework 4.6.1, 项目的目录结构,和WPF很相似
等待Nuget还原成功后,先构建一下项目,VS上可以直接像WPF一样所见即所得地使用设计器
修改一下MainWindow的界面代码以及后端代码,此处只给出与模板生成代码的git差异
看到DockPanel是不是有很熟悉的感觉?
在界面代码中,我对<Window>添加了 Width和Height的默认属性,在Windows系统下,这两个属性可以不用添加,程序启动后是正常的,但如果运行于OSX系统,不添加默认宽高,窗口会很小(虽然可以通过拖动来缩放)
调试运行
直接从VS进行调试运行,先跳出一个dotnet窗口,再跳出一个界面窗口,可见程序是运行在.NetCore运行时上的
点击按钮,如我所愿,显示了“Welcome to Avalonia!”
发布程序
我的目标是将程序发布到OSX平台
先运行 dotnet publish
发生了错误,提示项目是多目标框架的,需要指定发布目标框架
运行 dotnet publish -f=netcoreapp2.1
指定目标框架为 netcoreapp2.1,提示 error MSB1009:项目文件不存在
还是不行,那再试试发布到.net framework 4.6.1
dotnet publish -f=net461
发布成功
疑惑为什么无法发布到netcoreapp2.1下为什么会失败,所以我使用 .NetCore CLI创建了一个项目,对比两项目的 .csproj文件发现
使用.NetCore CLI创建的项目文件,使用的是单目标框架,而使用VS模板创建的项目文件,是多目标框架,
对比两个文件,对 .csproj文件进行修改,将项目更改为单目标框架 netcoreapp2.1
删除项目下的 bin 和 obj 文件夹, 并指定OSX平台发布
dotnet publish -r osx-x64
生成成功
将 \bin\Debug\netcoreapp2.1\osx-x64\publish 目录拷到 OSX 下(如果打包后复制,在OSX解压会丢失文件的权限属性,没有执行权限,需要重新授权)
通过命令行运行 MyAvalonia 程序,
程序窗口正常跳出
点击按钮
程序打包
成功了但不够完美,有没有办法打包成.app应用,直接点击就可以运行?
Google了很久,网上没有找到现成的打包工具,那就自己想想办法
使用Xcode创建了一个 Cocoa App, 项目名称可任意取(我取名为avalonia),直接build,生成一个 avalonia.app 文件,将 .app文件拷出,查看程序包结构
把 avaloina.app/Contents/MacOS 下所有文件(只有avalonia文件) 删除
把avaloina.app/Contents/Frameworks 下所有文件(很多 .dylib 文件)删除
把自己编译的程序 publish/ 下所有文件,拷贝到 avaloina.app/Contents/MacOS下
使用文本编辑器打开 avaloina.app/Contents/Info.plist,修改 CFBundleExecutable 对应的 String值, 从 avalonia 改为 MyAvalonia, 保存
直接点击运行 avalonia.app,成功出现MyAvalonia窗口界面。