翼度科技»论坛 编程开发 .net 查看内容

一步步教你在 Windows 上构建 dotnet 系应用的 UOS 软件安装包

3

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
本文将详细指导大家如何逐步为 dotnet 系列应用创建满足 UOS 统信系统软件安装包的要求。在这里,我们所说的 dotnet 系列应用是指那些能够在 Linux 平台上构建 UI 框架的应用,包括但不限于 CPF 应用、UNO 应用、Avalonia 应用等
基于 dotnet 系的自发布自包含的能力,可以将 dotnet 系的应用进行发布为独立应用,无需框架依赖,如此即可执行 deb 包的二进制打包过程,从而很方便对接上 UOS 统信系统软件安装包的要求
整体步骤可以分为三个大步骤:

  • 步骤一:发布应用
  • 步骤二:组织文件结构
  • 步骤三:打包 deb 文件
本文接下来将按照步骤顺序一步步告诉大家如何在 Windows 上为 dotnet 系的应用创建符合要求的 UOS 统信系统软件安装包。本文写于 2023.12.25 如果你阅读本文的时间距离编写时间过远,可能本文有些知识不正确
步骤一 发布应用

无论是 CPF 应用还是 UNO 应用或者 Avalonia 应用,在进行构建符合要求的 UOS 软件安装包的第一步都是对应用项目进行发布,且为了后续打包和分发的方便,十分推荐发布为独立应用。这些应用的大概的发布命令行如下,请根据你的实际需求进行更改
  1. dotnet publish -c release -r linux-x64 --self-contained true
复制代码
完成发布之后,咱即可拿发布出来的文件夹进行制作符合要求的 UOS 软件安装包。为了减少大家的学习成本,本文将一步步进行,本文在编写过程中,将会先略去在本文所没有用到的知识点。但请大家放心的是,按照本文的方法是可以构建出一个符合要求的 UOS 软件安装包,只有一些扩展可选部分的功能被本文略过
在进入步骤二之前,我推荐将发布的文件夹拷贝到 UOS 系统上测试一下,确保应用本身发布出来是能够正常运行
步骤二 组织文件结构

本文属于尽可能多的手动化打包过程,所使用的工具只有文本编辑器以及 WSL (适用于 Linux 的 Windows 子系统) 和 dpkg 工具。本文这里使用 WSL 仅仅只是为了使用 dpkg 工具而已,尽量使用官方推荐的打包工具。事实上,咱是完全可以将此过程在 Windows 上完成的。但为了减少引入额外的工具,本文依然使用 dpkg 工具进行打包,在本文后面,大家可以看到 dpkg 工具的戏份也只有一句话
2.1 准备打包环境

在开始之前,需要先准备好打包环境

  • 文本编辑器

    • 这里的文本编辑器可不推荐选用 Windows 自带的记事本哦。因为 Windows 自带的记事本绝大部分情况下的默认行为都会写入文件的 BOM 头,导致脆弱的 Linux 不认识而挂掉。如果一定要用 Windows 自带的记事本工具,记得保存选项里面选用的是 UTF-8 版本,不能选用 UTF-8 with BOM 等编码
    • 推荐使用 SublimeText 或 Vim 工具都可以

  • Debian 的 WSL 工具

  • dpkg 工具

    • 默认就在 Debian 里面带了,你只需要打开 Debian WSL 命令行,输入 dpkg 试试看,即可知道安装了没。如没安装,那随便网上搜搜就知道怎么安装了

为什么在 WSL 里面要选用 Debian 版呢?请自行搜搜 uos 和 debian 关系 你就知道咯
2.2 准备文件结构

开始之前的准备工作完成之后,接下来就可以开始正式的打包大业了。先来明确一下咱的目标:现在咱手头上有一个 Debian 的 WSL 工具,也有使用 UI 框架的应用进行独立发布之后的文件夹,意味着其二进制文件可以直接在 UOS 上双击运行。咱需要做的就是将独立发布之后的文件夹打进安装包里面,再搭配上 UOS 规范要求的图标、应用信息等即可
根据 应用打包规范 文档中心-统信UOS生态社区 文档,咱可以了解到符合 UOS 规范要求的安装包其实也是一个 deb 包。与之不同的只有文件结构组织形式,以及部分配置内容不相同而已
根据 如何构建符合要求的 UOS 软件安装包 - VVavE 文档,可以看到在 UOS 规范下的安装包的文件结构组织形式如下
  1. │  
  2. ├─DEBIAN
  3. │      control
  4. │      
  5. └─opt
  6.     └─apps
  7.         └─org.dotnetcampust.exampleapplication
  8.             │  info
  9.             │  
  10.             ├─entries
  11.             │  ├─applications
  12.             │  │      org.dotnetcampust.exampleapplication.desktop
  13.             │  │      
  14.             │  └─icons
  15.             │      └─hicolor
  16.             │          └─24x24
  17.             │              └─apps
  18.             │                      org.dotnetcampust.exampleapplication.png
  19.             │                     
  20.             └─files
  21.                 └─bin
  22.                     │  ExampleApplication
  23.                     │  ExampleApplication.deps.json
  24.                     │  ExampleApplication.dll
  25.                     │  ExampleApplication.pdb
  26.                     │  ExampleApplication.runtimeconfig.json
  27.                     │  ExampleApplication.uprimarker
  28.                     │  WindowsBase.dll
  29.                     │  Microsoft.CSharp.dll
  30.                     │  ...
复制代码
再次感谢 VVavE 潮汐博客 本文接下来将有大量知识内容来源于此
本文接下来将按照文件夹组织的顺序,告诉大家如何进行组织
2.2.1 DEBIAN 文件夹

安装包的文件结构组织的根目录包含了 DEBIAN 和 opt 两个文件夹。其中的 DEBIAN/ 文件夹是构建过程文件夹,包含软件包构建过程相关的控制文件。在本文这里,只需放入 control 构建控制文件即可,此文件完全遵照 Debian 官方规范
为了方便大家理解,本文将对 UnoFileDownloader 下载器 进行打包作为例子,方便大家了解手动打包的细节
在开始制作安装包的时候,咱还需要给应用进行命名,即对 AppID 应用的唯一标识进行命名。在 UOS 里采用和 Android 系统类似的规范,应用商店只接受使用域名倒置规则命名的应用。请务必使用厂商的倒置域名+产品名作为应用包名,如 com.example.demo 格式,前半部分为厂商域名倒置,后半部分为产品名,如果使用非拥有者的域名作为前缀,可能会引起该域名拥有者进行申诉,导致软件被申诉下架或者删除
这里必须特别强调,只允许小写字母。且在本文下方出现的任何 AppID 或 appid 或 ${appid} 等占位符里,都需要采用此应用的唯一标识字符串,请务必确保手工打包时,各处命名都是使用相同的字符串
本文这里对 UnoFileDownloader 下载器 命名为 org.dotnetcampust.unofiledownloader 应用。尽管看起来有些不习惯且可读性较差,但 UOS 官方规范就是这样,只有遵守咯
先创建工作文件夹,接下来咱的所有文件组织结构都在此工作文件夹进行。如我这里创建的是 C:\lindexi\Work 文件夹
在工作文件夹里面先创建 DEBIAN 文件夹,请确保大小写哦,在 Linux 上是大小写敏感的
进入 DEBIAN 文件夹,再创建名为 control 的文本文件。接着打开文本编辑器,编辑 control 文件。此 control 文件要求使用 UTF-8 格式编码,且是不带 BOM 头的。所谓 BOM 头就是在文件的前两个字节里面写入编码信息,这是在 Windows 上常用的方式,原本 BOM 头是用来指示编码大小端的,后续被大家更开森用在了识别区分文件的编码上了。使用 SublimteText 编辑时,默认的配置就是不带 BOM 头的
按照 Debian 的规范,编写 control 的文件的内容,如以下例子
  1. Package: org.dotnetcampust.unofiledownloader
  2. Version: 1.1.3
  3. Section: utils
  4. Priority: optional
  5. Architecture: amd64
  6. Multi-Arch: foreign
  7. Build-Depends: debhelper (>=9)
  8. Standards-Version: 3.9.6
  9. Maintainer: lindexi<lindexi_gd@outlook.com>
  10. Homepage: https://blog.lindexi.com/
  11. Description: 下载器.
复制代码
以上的 control 的各个字段/属性的说明如下,以下内容来自于 从零开始制作 deb 文件 - hzSomthing 博客

  • Package : 包的唯一标识符,即 AppID 值
  • Version : 安装包的版本号,即应用版本号。可使用 a.b.c 格式,也可以比较复杂的语义版本号格式,如 1.2.3-2+b1 等格式
  • Section : 这是软件包的分类子类别,可以选用 utils,admin, devel, doc, libs, net, 或者 unknown 等等,代表着该软件包在 Debian 仓库中将被归属到什么样的逻辑子分类中
  • Priority : optional 优先级适用于与优先级为 required、important 或 standard 的软件包不冲突的新软件包。也可以做其它取值。若是不明了,请使用 optional
  • Architecture : 目标系统的 CPU 架构,一般来说是 amd64,具体情况以后会有所讨论。有时候,它们可以是 any 或者 all
  • Maintainer : deb 包的维护者,及其邮件地址
  • Description : 软件包的描述信息。多行也可以,前面缩进至少一个空格
  • 最后一个空行 : 不能省略,否则打包提示 missing final newline 错误
在 DEBIAN/ 文件夹里面还可以包含其他的很多文件,只是本例子这里没有需求用到,就此略过。如感兴趣,请参阅 Debian 新维护者手册
2.2.2 opt 文件夹

完成 control 文件编写之后,接下来创建 /opt/apps/${appid}/ 文件夹,请将 ${appid} 替换为你的 AppID 值,此文件夹就是应用根目录文件夹
在本文这里也就是创建 C:\lindexi\Work\opt\apps\org.dotnetcampust.unofiledownloader\ 文件夹,请特别小心文件命名的小写问题
应用根目录下面应包含 files 和 entries 两个目录和一个 info 文件。文件结构如下
  1. │      
  2. └─opt
  3.     └─apps
  4.         └─org.dotnetcampust.exampleapplication
  5.             │  info
  6.             │  
  7.             ├─entries
  8.             │  ├─applications
  9.             │  │      org.dotnetcampust.exampleapplication.desktop
  10.             │  │      
  11.             │  └─icons
  12.             │      └─hicolor
  13.             │          └─24x24
  14.             │              └─apps
  15.             │                      org.dotnetcampust.exampleapplication.png
  16.             │                     
  17.             └─files
  18.                 └─bin
  19.                     │  UnoFileDownloader.Skia.Gtk
  20.                     │  ...
复制代码
以下继续按照此顺序逐个为大家介绍
2.2.2.1 files 文件夹

先创建 files 文件夹,按照规范上所述,可以在 files 文件夹里面塞入任意的文件,也包括应用的可执行文件。规范上建议将可执行文件放入到 files/bin 文件夹,咱是听话的开发者,于是将 dotnet publish -c release -r linux-x64 --self-contained true 的输出文件夹(我的是 X:\lindexi\Code\dotnetCampus.FileDownloader\src\UnoFileDownloader\UnoFileDownloader\UnoFileDownloader.Skia.Gtk\bin\Release\net8.0\linux-x64\publish\ 文件夹)的文件全部拷贝(移动)到 files/bin 文件夹里面
2.2.2.2 entries 文件夹

再创建 entries 文件夹,在 entries 文件夹里面应该放入的内容是桌面/开始菜单的图标以及应用启动信息。在 entries 文件夹里面再创建 applications 文件夹,在 applications 文件夹里面创建 AppId.desktop 文本文件。同理请将 AppId.desktop 的 AppId 换成你的应用标识符,在本文例子里面,将创建的是 C:\lindexi\Work\opt\apps\org.dotnetcampust.unofiledownloader\entries\applications\org.dotnetcampust.unofiledownloader.desktop 文件
接下来打开文本编辑器,编辑 .desktop 文本文件,同理要求此文件采用 UTF-8 编码格式。以下是 org.dotnetcampust.unofiledownloader.desktop 文件例子内容,此文件当前使用的是标准的 desktop 格式,相关标准及其他字段可以参考 https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html 文档或 desktop文件规范 - DeepinWiki 文档
  1. [Desktop Entry]
  2. Categories=Network
  3. Name=UnoFileDownloader
  4. Name[zh_CN]=简单的下载器
  5. Keywords=deepin;uniontech;downloader
  6. Keywords[zh_CN]=深度;统信;下载器
  7. Comment=The UnoFileDownloader can download file.
  8. Comment[zh_CN]=可以简单下载文件。
  9. Exec=/opt/apps/org.dotnetcampust.unofiledownloader/files/bin/UnoFileDownloader.Skia.Gtk
  10. Icon=org.dotnetcampust.unofiledownloader
  11. Type=Application
  12. Terminal=false
  13. StartupNotify=true
  14. MimeType=audio/aac;application/aac;
复制代码
以下是从官方文档 里抄到的 Desktop 文件中重点字段的解释

  • [Desktop Entry]:        必填         desktop文件标识,标准格式,不需要改动。
  • Categories:         选填         程序分类,用于标注程序所属类型。该字段不存在时,应用属于“其他应用”。
  • Name:         必填         程序在启动器中显示的通用名称,在没有单独设置语言参数的情况下,默认显示该名称。
  • Keywords:         选填         程序的通用关键搜索词,当在启动器中搜索该词而非程序名称时,即可索引出该程序的快捷方式。
  • Comment:         选填         关于本程序的通用简述,在没有单独设置语言参数的情况下,默认显示该段内容。
  • Exec:         必填         应用的运行程序所在路径,一般为程序的可执行二进制文件或启动脚本,后期会被沙箱启动。 填写时需要关注路径的有效性,如果路径无效,在安装该程序后,程序快捷方式将不会显示在启动器中。一般都是 /opt/apps/${appid}/files/bin/Xxxxx 文件路径,这个路径请关注一下文件命名大小写问题,防止因为大小写不相同导致路径文件找不到,请将 Xxxxx 替换为你的构建输出的可执行程序
  • Icon :        必填         显示的图标所在路径,推荐使用相对名称以便于系统根据主题规范查找对应的图标文件,特殊情况下(显示异常等)需要使用绝对路径来获取图标。按照图标命名的约定,基本上这里填写的就是 ${appid} 的值,不需要带上图片后缀名
  • Type:         必填         程序类型,必须为“Application”。
  • Terminal :        必填         该字段决定程序是否以终端的形式运行,默认为“false”关闭状态,若该项为“true”开启状态,则应用将会在终端中打开。即设置为 true 时,将以命令行控制台方式启动
  • StartupNotify:         必填         程序是否支持发送启动通知事件。为“true”时,允许桌面环境跟踪应用程序的启动,提供用户反馈和其他功能。例如鼠标的等待动画等。为保障应用使用体验,该项建议填写“true”。
  • MimeType :        选填         程序支持的关联文件类型,根据实际需求来填写。如果没有需要支持关联文件,则可以整行不写
Categories 应用类型可参考以下填写值来设置

  • Network: 网络应用
  • Chat: 社交沟通
  • Audio: 音乐欣赏
  • AudioVideo: 视频播放
  • Graphics: 图形图像
  • Game: 游戏娱乐
  • Office: 办公学习
  • Reading: 阅读翻译
  • Development: 编程开发
  • System: 系统管理
除上述分类外,填写其他分类将会被归为“其他应用”
完成 .desktop 文本文件,接下来再创建 icons 文件夹用来存放应用图标。图标可以使用 svg 矢量格式和 png 非矢量格式。尽管官方文档说的是非矢量格式建议使用 png 格式,然而实际是只能使用png格式,我试过 jpg 等其他格式都不生效,都会被替换为默认的应用图标,将 jpg 改后缀为 png 也是不行的
矢量格式图标只需放一份,路径是 entries/icons/hicolor/scalable/apps/${appid}.svg 请在放入图标之后,拷贝其路径与本文档进行对比,看是否文件夹层级正确
如果使用非矢量格式,请按照 分辨率 来放置图标,如:
  1. entries/icons/hicolor/24x24/apps/${appid}.png
  2. entries/icons/hicolor/16x16/apps/${appid}.png
复制代码

  • 支持的分辨率包括: 16/24/32/48/128/256/512 ,不同分辨率的图标会被用在不同的地方,比如桌面、通知栏、任务栏、应用抽屉中,如果没有全部包括则会自动进行缩放,影响最终效果
  • 强烈建议遵循分辨率放置目录,尽量不要在 128x128 文件夹内放置其他分辨率的图标
  • 如果实在没有其他分辨率资源,只有一个分辨率图标,放置在 128x128 文件夹即可
同样,在放入图标之后,请拷贝其路径与本文档进行对比。我在制作安装包时,就因为少了一层 hicolor 文件夹,调查了半天才发现是文件夹层级不对
2.2.2.3 info 文件

完成应用根目录下面包含的 entries 和 files 两个目录之后,接下来开始编写 info 文件。此文件是应用的描述文件,用于dde桌面环境安装软件包时自动配置程序的安装文件,使用 JSON 格式,内容一般如下
  1. {
  2.         "appid": "org.dotnetcampust.unofiledownloader",
  3.         "name": "UnoFileDownloader",
  4.         "version": "1.1.3",
  5.         "arch": ["amd64", "arm64"],
  6.         "permissions":
  7.         {
  8.                 "autostart": false,
  9.                 "notification": false,
  10.                 "trayicon": false,
  11.                 "clipboard": false,
  12.                 "account": false,
  13.                 "bluetooth": false,
  14.                 "camera": false,
  15.                 "audio_record": false,
  16.                 "installed_apps": false
  17.         }
  18. }
复制代码

  • appid : 填入的就是 ${appid} 内容,作为应用标识,软件包名
  • name :应用默认名称,允许和其他应用重名
  • version :应用版本,使用 {MAJOR}.{MINOR}.{PATCH}.{BUILD} 格式,即 [主线版本].[次要版本].[补丁版本].[构建版本] 格式,所有版本号均为纯数字。此处填写的值应与deb安装包所标识的版本号一致,即和 DEBIAN/control 的 Version 相同
  • arch :应用支持的架构,目前商店支持以下几种架构 amd64, mips64el, arm64, sw_64, loongarch64
  • permissions :应用权限。开发者需要注意,应用只允许使用普通用户权限启动,禁止应用以任何形式 root 提权。此部分只限制通过 Dbus 调用,其他方式调用则无影响。具体含义如下
  • autostart : 是否允许自启动
  • notification : 是否允许使用通知
  • trayicon : 是否运行显示托盘图标
  • clipboard : 是否允许使用剪切板
  • account : 是否允许读取登录用户信息
  • bluetooth : 是否允许使用蓝牙设备
  • camera : 是否允许使用视频设备
  • audio_record : 是否允许进行录音
  • installed_apps : 是否允许读取安装软件列表
这里需要额外提醒大家,在 UOS 的官方文档提供的 info 文件例子里面,其文件内容的 json 格式是错误的,在 permissions 属性和下一个属性之间少了一个逗号,如果想要拷贝官方的例子,还请自行确保 json 格式正确

写到这里,文件结构就完成了,本例子完成之后的文件结构如下
  1. C:\lindexi\Work
  2. │  
  3. ├─DEBIAN
  4. │      control
  5. │      
  6. └─opt
  7.     └─apps
  8.         └─org.dotnetcampust.unofiledownloader
  9.             │  info
  10.             │  
  11.             ├─entries
  12.             │  ├─applications
  13.             │  │      org.dotnetcampust.unofiledownloader.desktop
  14.             │  │      
  15.             │  └─icons
  16.             │      └─hicolor
  17.             │          └─24x24
  18.             │              └─apps
  19.             │                      org.dotnetcampust.unofiledownloader.png
  20.             │                     
  21.             └─files
  22.                 └─bin
  23.                     │  UnoFileDownloader.dll
  24.                     │  UnoFileDownloader.pdb
  25.                     │  UnoFileDownloader.Skia.Gtk
  26.                     │  UnoFileDownloader.Skia.Gtk.deps.json
  27.                     │  UnoFileDownloader.Skia.Gtk.dll
  28.                     │  UnoFileDownloader.Skia.Gtk.pdb
  29.                     │  UnoFileDownloader.Skia.Gtk.runtimeconfig.json
  30.                     │  UnoFileDownloader.uprimarker
  31.                     │  WindowsBase.dll
  32.                     │  Microsoft.CSharp.dll
  33.                     │  ...
复制代码
完成了文件结构,下面将进入打包环境,开始创建 deb 包
步骤三 打包 deb 文件

本例子打包采用的是 Debian 的 WSL 里的 dpkg 工具进行创建 deb 文件,开始之前请确保准备好 Debian 环境。下载地址:https://www.microsoft.com/store/productId/9MSVKQC78PK6?ocid=pdpshare
先使用 cd 命令进入工作路径,如本文例子使用的 C:\lindexi\Work 文件夹
  1. cd /mnt/c/lindexi/Work
复制代码
进入其他盘符请使用 /mnt/[盘符] 的方式。值得一提的是 WSL 里面对中文支持还不错,可以放心进入中文文件夹
进入之后使用 ls 命令确保进入正确的文件夹,预期输出如下
  1. lindexi@DESKTOP-51A5UGG:/mnt/c/lindexi/Work$ ls
  2. DEBIAN  opt
复制代码
接下来输入 dpkg-deb -b . 命令进行打包
  1. lindexi@DESKTOP-51A5UGG:/mnt/c/lindexi/Work$ dpkg-deb -b . UnoFileDownloader.deb
  2. dpkg-deb: building package 'org.dotnetcampust.unofiledownloader' in 'UnoFileDownloader.deb'.
复制代码
如此拿到的 UnoFileDownloader.deb 包就是可在 UOS 上使用的安装包文件
文件权限

在 WSL 里面 dpkg-deb 打包时,如果和我一样采用的是挂载某个磁盘路径,且磁盘是 NTFS 格式时,可能会遇到如下错误提示
[code]dpkg-deb: error: control directory has bad permissions 777 (must be >=0755 and

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具