Electron 应用构建支持统信 UOS 系统安装使用的方法
- 前端开发
- 2025-08-07
- 639热度
- 0评论
Electron 类项目通过 electron-builder
中的 linux
平台下的 deb
配置可一键打包出 deb 安装包。此类包可以在 UOS
系统中安装(一般会安装到 /opt
目录下),但点击快捷键无反应,通过命令行形式运行则提示 sandbox 相关错误。
1 关于 sandbox 异常的解决方法
一种简单的解决办法是修改快捷键文件,添加 --no-sandbox
启动参数。
假若文件位置为 /usr/share/applications/me.lzw.app.desktop
,编辑它,并在 Exec
行后添加 --no-sandbox
,示例:
Exec=/opt/me.lzw.app/me.lzw.app --no-sandbox
2 Electron 应用构建支持 no-sandbox
启动参数
通过 electron-builder
构建的应用,可以通过设置 executableArgs
参数来添加启动参数,示例配置:
{
"linux": {
"maintainer": "[email protected]",
"executableArgs": ["--no-sandbox"],
"target": ["AppImage", "deb"],
"icon": "build/linux/icons/",
"category": "Development",
"extraResources": ["./config/**/*"],
"desktop": {
"Icon": "./build/icons/256x256.png",
"StartupNotify": "false",
"Encoding": "UTF-8",
"MimeType": "x-scheme-handler/deeplink"
}
// "postInstallscript": "build/linux/postinst.sh",
}
}
注意:如果是比较低版本的 electron
和 electron-builder
,可能不支持 executableArgs
参数配置。可参考下文方法,构建一个符合 UOS 应用程序规范的 deb 安装包。
3 二进制应用构建为支持 UOS 应用程序规范的安装包
通过 electron-builder
构建出来的 deb
包和统信 UOS 应用程序规范有所差异,如果是希望上架其应用商店,还需按其应用程序规范组织目录结构。规范参考:
通过 electron-updater
打包后,在 release 目录会有一个 linux-unpacked
或 linux-arm64-unpacked
目录,这里包含了应用程序运行所需的所有文件。
参考如上规范,我们创建如下目录结构:
uos-tmp
临时目录opt/apps/me.lzw.app
应用程序安装位置opt/apps/me.lzw.app/info
应用程序信息文件opt/apps/me.lzw.app/files
应用程序文件,将linux-unpacked
目录下的内容拷贝过来opt/apps/me.lzw.app/entries/applications/me.lzw.app.desktop
快捷方式,安装后会映射到/usr/share/applications/me.lzw.app.desktop
,然后就可以在启动器中看到该应用了DEBIAN
debian 包结构control
包的基本信息install
安装脚本
基于如上目录规范,我基于 Node.js 写了一个脚本,用于一键打包,参考:
const { resolve } = require('node:path');
const { writeFileSync } = require('node:fs');
const { execSync } = require('node:child_process');
const { mkdirp, rmrf } = require('@lzwme/fe-utils');
const { env, rootDir, argv } = require('./helper');
async function packForUOS(arch = argv.arch || 'arm64') {
const epkg = require('../../dist/electron/app/package.json');
const baseDir = resolve(rootDir, 'release');
const appId = `lzw.me.app${env}`;
const version = epkg.version;
const uosPackTmpDir = resolve(baseDir, `${appId}-${version}`);
const appDest = resolve(uosPackTmpDir, `opt/apps/${appId}`);
const architecture = arch === 'x64' ? 'amd64' : arch === 'x86' ? 'i386' : arch;
rmrf(resolve(baseDir, appId));
mkdirp(resolve(appDest, 'entries/applications'));
mkdirp(resolve(appDest, 'files'));
execSync(`cp -R linux${arch === 'x64' ? '' : arch === 'x86' ? '-ia32' : `-${arch}`}-unpacked/* ${appDest}/files`, { stdio: 'inherit', cwd: baseDir });
execSync(`cp -R ../dist/electron/builder/res/256x256.png ${appDest}/files/icon.png`, {
stdio: 'inherit',
cwd: baseDir,
});
// 生成 info 文件
const info = {
appid: appId,
name: epkg.name,
version: version,
arch: architecture === 'all' ? ['amd64', 'arm64'] : [architecture],
permissions: {
autostart: false,
notification: true,
trayicon: true,
clipboard: true,
account: true,
bluetooth: true,
camera: true,
audio_record: true,
installed_apps: true,
network: true,
filesystem: true,
},
};
writeFileSync(resolve(appDest, 'info'), JSON.stringify(info, null, 4), 'utf8');
// 生成 desktop 文件
const desktopFile = resolve(appDest, `entries/applications/${appId}.desktop`);
const desktopContent = [
`[Desktop Entry]`,
`Name=${info.name}`,
`Name[zh-CN]=${epkg.appName}`,
`Comment=${epkg.description}`,
`Exec=/opt/apps/${appId}/files/lzwme-${env} --no-sandbox --enable-gpu-rasterization --disable-gpu-sandbox %U`,
`Icon=/opt/apps/${appId}/files/icon.png`,
`Categories=Utility;`,
`Terminal=false`,
`Type=Application`,
`StartupNotify=true`,
`Encoding=UTF-8`,
].join('\n');
writeFileSync(desktopFile, desktopContent, 'utf8');
// 生成 debian 目录及文件
const debianDir = resolve(uosPackTmpDir, `DEBIAN`);
mkdirp(debianDir);
const debianControl = [
`Source: ${appId}`,
`Section: unknown`,
`Priority: optional`,
`Maintainer: lzw.me <[email protected]>`,
`Build-Depends: debhelper (>= 11)`,
`Standards-Version: 4.1.3`,
`Homepage: https://lzw.me`,
`Package: ${appId}`,
`Version: ${version}`,
`Architecture: ${architecture}`,
`Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libdrm2, libgbm1, libasound2`,
`Description: ${epkg.appName}`,
` ${epkg.description}\n`,
].join('\n');
writeFileSync(resolve(debianDir, 'control'), debianControl, 'utf8');
// 生成 install 文件
writeFileSync(resolve(debianDir, 'install'), `opts/apps/${appId}/ /opt/apps`, 'utf8');
execSync(`dpkg-deb -b ${uosPackTmpDir}/ lzwme-${env}-uos-${arch}-${info.version}.deb`, { stdio: 'inherit', cwd: baseDir });
}
if (require.main === module) packForUOS(argv.arch);
module.exports = packForUOS;
在 electron-builder
构建完成后,继续执行该脚本,即可生成所需符合 uos
应用程序规范的 deb
安装包。
4 相关参考
- https://uosdn.uniontech.com/#document3?dirid=656ef27dbd766615b0b0300e&id=65702eaebd766615b0b0310d
- https://blog.csdn.net/weixin_45813250/article/details/117027334
- https://blog.csdn.net/weixin_43855876/article/details/107251980
- https://blog.csdn.net/Karim_Benzema/article/details/136351345
- https://www.bilibili.com/opus/503101456761048630