虽然工作开发语言已经转到了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窗口界面。