C# .NET core Avalonia 11.0版本,发布linux和MAC的简单记录
.net core 7.0+centos 7.0
cetnos目前运行在hyper V虚拟机里
虚拟机部署的注意事项
1 需要配置网络环境,
确保在同一局域网下
如果sftp无法连接
ctrl+shift+f2切换到命令行,开启22端口
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
同时虚拟机网络也要正确配置.
发布流程如下
1 发布项目,选择目标运行时为linux-X64,部署模式为独立,这样就不需要安装.net core运行环境,此处可根据实际情况自行调整下
如图设置即可
2
发布后,使用Xftp上传
以上传到/usr/local/bin/Test2 目录下为例
3
右击目标运行文件,通常为项目名,没有后缀名
选择可执行
4
打开kconsole,cd切换到目标路径
执行 ./AvaloniaTest ,此处AvaloniaTest 为目标文件名
4
项目正常运行
常见问题:
1 default font familyname can't be null
提示缺少默认字体,需要指定字体
参考github上的链接,设置默认字体后依然报错
https://github.com/AvaloniaUI/Avalonia/issues/4427
using Avalonia; using Avalonia.Media; using Avalonia.ReactiveUI; using System; namespace ExampleApp { internal class Program { [STAThread] public static void Main(string[] args) => BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); public static AppBuilder BuildAvaloniaApp() { FontManagerOptions options = new(); if (OperatingSystem.IsLinux()) { options.DefaultFamilyName = "<Linux Default Font Family Name Here>"; } else if (OperatingSystem.IsMacOS()) { options.DefaultFamilyName = "<macOS Default Font Family Name Here>"; } // No need to set default for Windows return AppBuilder.Configure<App>() .UsePlatformDetect() .LogToTrace() .UseReactiveUI() .With(options); } } }
FontFamily = new FontFamily("avares://AvaloniaTest/Assets/Fonts/微软雅黑.ttf#Microsoft YaHei")
不行,报错为
could not create glyphtypeface
如果报这个错误,参考问题2
/usr/share/fonts/chinese/msyh.ttc
运行fc-cache -f -v 命令,更新字体缓存
fc-cache -f -v
修改Program.cs
public static AppBuilder BuildAvaloniaApp() { FontManagerOptions options = new(); options.DefaultFamilyName = "Microsoft YaHei"; return AppBuilder.Configure<App>() .UsePlatformDetect() .WithInterFont() .LogToTrace() .UseReactiveUI().With(options); }
重新发布,即可.
mac版本
测试环境:
avalonia+cefnet 跨平台浏览器套壳demo
demo为双浏览器界面
M2 arm 处理的mac系统
虚拟机,都运行通过.
直接编译后拷贝到任意位置
就可以直接运行了
demo为调用cefnet核心的avalonia项目
问题:
把编译后的.app文件,打包成zip后拷贝到mac,再解压缩,会无法运行,原因不明.
解决方法,mac打包成dmg文件,再分发.
没有签名也可以分发.就是会多一次提示.
打包命令
hdiutil create -srcfolder [源文件夹路径] [目标DMG文件路径]
附mac打包脚本,以cefnet为例
create_app_structure() { APPNAME=$1 APPDIR="$APPNAME.app/Contents" APPICONS="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns" if [ ! -d "$APPDIR" ]; then echo "creating app structure $APPDIR" mkdir -vp "$APPDIR"/{Resources,Frameworks} cp -v "$APPICONS" "$APPDIR/Resources/$APPNAME.icns" fi } emit_plist() { PLIST_APPNAME=$1 PLIST_PATH="$2/Info.plist" if [ "$3" ]; then LSUIELEMENT="false" else LSUIELEMENT="true" fi if [ ! -f "$PLIST_PATH" ]; then echo "emiting $PLIST_PATH" cat <<EOF > "$PLIST_PATH" <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleExecutable</key> <string>$PLIST_APPNAME</string> <key>CFBundleGetInfoString</key> <string>$PLIST_APPNAME</string> <key>CFBundleIconFile</key> <string>$PLIST_APPNAME</string> <key>CFBundleName</key> <string>$PLIST_APPNAME</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleSignature</key> <string>????</string> <key>LSUIElement</key> <string>$LSUIELEMENT</string> </dict> </plist> EOF fi } BINARYNAME="AvaloniaApp" CONFIGURATION="Debug" NETTARGET="net7.0" OS_ARCH=`/usr/bin/arch` if [ $OS_ARCH = arm64 ]; then CEFZIP="cef_binary_105.3.18%2Bgbfea4e1%2Bchromium-105.0.5195.52_macosarm64_beta_minimal.tar.bz2" RID="osx-arm64" else CEFZIP="cef_binary_105.3.18%2Bgbfea4e1%2Bchromium-105.0.5195.52_macosx64_beta_minimal.tar.bz2" RID="osx-x64" fi TARGET="bin" if [ ! -d "$TARGET" ]; then mkdir "$TARGET" fi cd "$TARGET" echo "Building CefNet Avalonia demo..." dotnet publish ../AvaloniaApp/AvaloniaApp.csproj -c "$CONFIGURATION" -r $RID -f "$NETTARGET" -o "publish" --self-contained CEFBINARIES="../cef" CEFFRAMEWORK_DIR="$(find $CEFBINARIES -name "Release")" if [ ! -d "$CEFFRAMEWORK_DIR" ]; then if [ ! -f "$CEFBINARIES/$CEFZIP" ]; then echo "downloading cef binaries from https://cef-builds.spotifycdn.com/$CEFZIP" curl -o "$CEFBINARIES/$CEFZIP" "https://cef-builds.spotifycdn.com/$CEFZIP" fi echo "unzipping cef binaries" tar -jxvf "$CEFBINARIES/$CEFZIP" --strip-components 1 -C "./$CEFBINARIES" CEFFRAMEWORK_DIR="$(find $CEFBINARIES -name "Release")" fi APPNAME="$BINARYNAME" APPDIR="$APPNAME.app/Contents" rm -rf "$APPDIR" create_app_structure "$APPNAME" emit_plist "$APPNAME" "$APPDIR" true cp -R "$CEFFRAMEWORK_DIR/Chromium Embedded Framework.framework" "$APPDIR/Frameworks/" cd "$APPDIR/Frameworks" APPNAME="$BINARYNAME Helper" APPDIR="$APPNAME.app/Contents" create_app_structure "$APPNAME" emit_plist "$APPNAME" "$APPDIR" cp -R "../../../publish/" "$APPDIR/MacOS" ln -s "Frameworks/$APPDIR/MacOS" "../MacOS" chmod +x "$APPDIR/MacOS/$BINARYNAME" cp "$APPDIR/MacOS/$BINARYNAME" "$APPDIR/MacOS/$APPNAME" chmod +x "$APPDIR/MacOS/$APPNAME" APPNAME="$BINARYNAME Helper (GPU)" APPDIR="$APPNAME.app/Contents" mkdir -pv "$APPDIR" emit_plist "$APPNAME" "$APPDIR" ln -s "../../$BINARYNAME Helper.app/Contents/MacOS" "$APPDIR/MacOS" cp "$APPDIR/MacOS/$BINARYNAME" "$APPDIR/MacOS/$APPNAME" chmod +x "$APPDIR/MacOS/$APPNAME" APPNAME="$BINARYNAME Helper (Plugin)" APPDIR="$APPNAME.app/Contents" mkdir -pv "$APPDIR" emit_plist "$APPNAME" "$APPDIR" ln -s "../../$BINARYNAME Helper.app/Contents/MacOS" "$APPDIR/MacOS" cp "$APPDIR/MacOS/$BINARYNAME" "$APPDIR/MacOS/$APPNAME" chmod +x "$APPDIR/MacOS/$APPNAME" APPNAME="$BINARYNAME Helper (Renderer)" APPDIR="$APPNAME.app/Contents" mkdir -pv "$APPDIR" emit_plist "$APPNAME" "$APPDIR" ln -s "../../$BINARYNAME Helper.app/Contents/MacOS" "$APPDIR/MacOS" cp "$APPDIR/MacOS/$BINARYNAME" "$APPDIR/MacOS/$APPNAME" chmod +x "$APPDIR/MacOS/$APPNAME"