electron使用electron-builder进行MacOS的 打包、签名、公证、上架、自动更新

一、前言

由于electron在macOS下的坑太多,本文不可能把所有的问题都列出来,也不可能把所有的解决方案贴出来;本文也不太会讲解每一个配置点为什么要这么设置的原因,因为有些点我也说不清,我尽可能会说明的。所以,你要抛弃你之前所有已经完成的东西,最好弄一个全新的系统,严格按照本文的步骤做。

建议用vmware虚拟机,装一个全新的macOS系统。配合vmware的拍照功能,如果中途出错,可以回退到虚拟机的上一个正常状态,非常方便。

我也是在这篇文章以及网友的帮助下才走通这个流程的,你可以参考一下。

Electron-builder 构建MacOS应用小白教程(打包 & 签名 & 公证 & 上架) - 掘金

二、系统配置

如果你需要这个环境,请私信我,200元送你(如果你需要,请在csdn上私信我,或者评论区留言,我会联系你的)。

我也是从别人那花钱买来的,另外我也是花钱各种请教,才总结出来的经验。当然,文档当中,我也会尽可能把我的经验放进去。

  • VMware® Workstation 17 Pro(17.0.0 build)

  • macOS Sonoma (版本14.0 Beta版) 

  • Xcode (Version 15.1) 

三、基本信息假设

由于配置需要一些信息,现对一些配置项做出假设

1.  您的appleId账号是 996@qq.com

https://idmsa.apple.com/

https://developer.apple.com

四、证书申请

1、加入 苹果应用开发者

这玩意需要交钱,按年付费,现在没法给大家截图了。只记得当时的坑是,得用比较新的 iphone 或者 mac,下载官方提供的一个应用,在里面注册提交资料即可。

https://developer.apple.com/programs/

2、生成 证书签名请求证书 文件

(1)按以下顺序,会在桌面生成一个 “CertificateSigningRequest.certSigningRequest” ,注意保存好该文件,以后要用的到。

(2)与此同时,会在钥匙串中生成一对密钥,这就是公钥和私钥,很重要,尤其私钥,如图所示

将这两个密钥导出后保存下来。这个私钥导出后,可以给别的开发人员用。别的开发人员导入这个“私钥文件和证书(.cer后缀的文件,在本文的后面会生成)文件”后,就可以在他的电脑上打包了。

下图就是本次生成的 证书签名请求文件、公钥、私钥文件

关于证书的知识,看这个文章:

https://www.jianshu.com/p/1e5f04ad396c/

https://www.jianshu.com/p/81610614225d

3、创建证书 Certificates

注意,不要在xcode里面创建证书(新版本的xcode里面创建不了 Mac Installer Distribution 证书;且不要用Apple Distribution 证书)

打开网址:

https://developer.apple.com/account

按以下步骤生成五个证书

将证书下载好后,按如下名称命名,以后要用。

4、创建 appId (即 Identifiers )

此处创建的:

bundle ID:cn.kafaka.greader

我自己账号的TeamID:GN5XP7HD2C 

上面两个合起来,就是 appId: GN5XP7HD2C.cn.kafaka.greader (注意后面的打包配置文件中有个appId配置项,不一定完全是这个,我会在那个配置文件中做 特别 说明)

5、添加 Devices

在electron-builder中,可以打包出mas和mas-dev两个目标项。mas打包出来的 pkg 要上传到 应用商店 Mac App Store(简称 mas);mas-dev打包出来的 app,要做本地测试,如果该app能正常运行,那么mas中打包出来的pkg就没问题。

而打包mas-dev时,要在应用中嵌入设备的uuid,该uuid会在下一步创建Profile时用到。

这里获取到的 uuid是 :564DBF37-1976-5C42-B5B9-584D407DB380

如果截图中的 硬件 UUID 和 预置UUID不一样,那就用 硬件uuid。如果实在不行,你把两个uuid都添加到 Devices中。

6、创建 Profiles 

按以下步骤生成3个Profiles

五、项目基本配置

1、图标生成

你搜索一个 electron-icon-builder 关键词吧,能找到的

2、plist文件

(1)entitlements.mac.inherit.plist

<?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>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.inherit</key>
    <true/>
</dict>
</plist>

(2)entitlements.mac.plist

<?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>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
	<true/>
	<key>com.apple.security.cs.allow-dyld-environment-variables</key>
	<true/>
</dict>
</plist>

 (3)entitlements.mas.inherit.plist

<?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>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.inherit</key>
    <true/>
</dict>
</plist>

(4)entitlements.mas.plist

注意,本文件中的 三个部分,得更改为你自己的。该文件中的其它部分内容,你可以根据自己的情况修改。

    <key>com.apple.security.application-groups</key>
    <array>
        <string>GN5XP7HD2C.cn.kafaka.greader</string>
    </array>


    <key>com.apple.application-identifier</key>
    <string>GN5XP7HD2C.cn.kafaka.greader</string>

    <key>com.apple.developer.team-identifier</key>
    <string>GN5XP7HD2C</string>

<?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>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
	<true/>
	<key>com.apple.security.cs.allow-dyld-environment-variables</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>GN5XP7HD2C.cn.kafaka.greader</string>
	</array>
	<key>com.apple.application-identifier</key>
	<string>GN5XP7HD2C.cn.kafaka.greader</string>
	<key>com.apple.developer.team-identifier</key>
	<string>GN5XP7HD2C</string>
	<key>com.apple.security.files.bookmarks.app-scope</key>
	<true/>
	<key>com.apple.security.files.bookmarks.document-scope</key>
	<true/>
</dict>
</plist>

你可以根据自己的情况,可添加以下内容

         // 看名字就知道与 用户选则文件相关
        <key>com.apple.security.files.user-selected.read-only</key>
        <true/>
        <key>com.apple.security.files.user-selected.read-write</key>
        <true/>

        // 看名字就知道与 下载相关
        <key>com.apple.security.files.downloads.read-write</key>
        <true/>

        // 看名字就知道与 网络访问相关

       <key>com.apple.security.network.client</key>
        <true/>
        <key>com.apple.security.network.server</key>
        <true/>

3、package.json

注意其中使用的 electron 和 electron-builder(高版本的已经直接把签名 公证等功能集成到一块了,比较省事;如果你用底版本,可能需要自己添加各种包,可能会出现其它问题)的版本号

    "devDependencies": {
        "electron": "^28.0.0",
        "electron-builder": "^24.9.1"
    },

关于会被打包的文件:dependencies会自动打包进去的;devDependencies不会打包进去,只是在开发时执行各种打包命令用的;builder中的files选项,用来指定哪些文件打包进去, 如果不指定,可能会把项目根目录下的所有文件打包进去。

打包时,electron-builder 会自动下载 electron版本,会缓存在以下目录中,可以自行下载好后放进去:

https://registry.npmmirror.com/binary.html?path=electron/

Linux: $XDG_CACHE_HOME or ~/.cache/electron/
MacOS: ~/Library/Caches/electron/
Windows: %LOCALAPPDATA%/electron/Cache or ~/AppData/Local/electron/Cache/

{
    "name": "electron-quick-start",
    "version": "1.3.2",
    "description": "A minimal Electron application",
    "main": "src/main.js",
    "scripts": {
        "start": "electron .",
        "pack": "electron-builder --dir",
        "dist": "electron-builder",
        "postinstall": "electron-builder install-app-deps"
    },
    "repository": "https://github.com/electron/electron-quick-start",
    "keywords": [
        "Electron",
        "quick",
        "start",
        "tutorial",
        "demo"
    ],
    "author": "GitHub",
    "license": "CC0-1.0",
    "devDependencies": {
        "electron": "^28.0.0",
        "electron-builder": "^24.9.1"
    },
    "dependencies": {},
    "build": {
        "appId": "cn.kafaka.greader",
        "files": [
            "src/*"
        ],
        "mac": {
            "category": "public.app-category.utilities",
            "target": [
                {
                    "target": "mas",
                    "arch": "universal"
                }
            ],
            "icon": "./build/icons/icon.icns"
        }
    }
}

4、项目结构预览

请注意:build里面是存放一些打包资源的,electron-builder未配置时,默认从这个文件夹中找一些配置英,所以不要改这个文件夹名字。

六、打包 mas

1、package.json

注意:

(1)看好mac、mas、dmg部分的配置,如果你没成功,就仔细对比和我的区别,配置的项不要多、不要少、位置也不要变。

(2)不要自作聪明,自认为加一点配置或者少一点配置就没问题,因为有些坑,我实在说不完,所以就不说了,你照着配置就好

{
    "name": "electron-quick-start",
    "version": "1.3.2",
    "description": "A minimal Electron application",
    "main": "src/main.js",
    "scripts": {
        "start": "electron .",
        "pack": "electron-builder --dir",
        "dist": "electron-builder",
        "postinstall": "electron-builder install-app-deps"
    },
    "repository": "https://github.com/electron/electron-quick-start",
    "keywords": [
        "Electron",
        "quick",
        "start",
        "tutorial",
        "demo"
    ],
    "author": "GitHub",
    "license": "CC0-1.0",
    "devDependencies": {
        "electron": "^28.0.0",
        "electron-builder": "^24.9.1"
    },
    "dependencies": {},
    "build": {
        "appId": "cn.kafaka.greader",
        "files": [
            "src/*"
        ],
        "mac": {
            "category": "public.app-category.utilities",
            "target": [
                {
                    "target": "mas",
                    "arch": "universal"
                }
            ],
            "icon": "./build/icons/icon.icns"
        },
        "mas": {
            "identity": "penghui deng (GN5XP7HD2C)",
            "hardenedRuntime": false,
            "gatekeeperAssess": false,
            "entitlements": "./build/entitlements.mas.plist",
            "entitlementsInherit": "./build/entitlements.mas.inherit.plist",
            "provisioningProfile": "./build/greader_mac_app_distribution.provisionprofile"
        },
        "dmg": {
            "sign": false,
            "background": "./build/osx/dmg_bk.png",
            "icon": "./build/icons/icon.icns",
            "iconSize": 120,
            "iconTextSize": 14,
            "contents": [
                {
                    "x": 112,
                    "y": 165
                },
                {
                    "x": 396,
                    "y": 165,
                    "type": "link",
                    "path": "/Applications"
                }
            ],
            "window": {
                "height": 380
            }
        }
    }
}

2、安装证书

将以下3个证书安装(双击cer文件运行,或者 把cer文件拖拽到 钥匙串访问 应用中)到钥匙串 的"登录"中。

安装好后,要包含以下3个。

证书安装成功后,有每个证书有以下两个特点:

(1)看到没,证书前面有个“小三角”,说明证书关联到 证书密钥的;密钥就是前面创建的 证书签名请求 文件: “CertificateSigningRequest.certSigningRequest”

(2)再看,点击证书后,上面有个“此证书有效”。如果不是这个结果,你得装该证书的的“签发者”证书,把下面4个证书下载下来装上。下载地址:https://developer.apple.com/account/resources/certificates/add

3、打包

(1)确保系统日期没问题,系统日期是 中国大陆区,时间和 北京时间是一样的,如果要修正日期,可用命令行:

方法一:调整时区,让系统自动调整。
sudo systemsetup -settimezone "Asia/Shanghai"

如果上面的命令没有把日期调整过来,你可以试着重启系统。


方法二:如果方法一不行,那就得强制手动改时间了。
sudo systemsetup -settimezone "Asia/Shanghai"
sudo systemsetup -setusingnetworktime off
sudo date <月><日><小时><分钟><年>

// 例如:要将日期设置为 2023 年 8 月 8 日,时间为下午 2 点 30 分,您可以执行以下命令:sudo date 080214302023

sudo systemsetup -setusingnetworktime on

如果时间不正确,可能出现如图所示的 时间戳问题

(2) 在项目根目录下执行这个命令

chmod -R a+rw ./*

如果不执行,可能在 Transporter 提交时出现如下问题

(3)更改package.json 中的版本号

(4)执行以下命令进行打包

 打包运行后,命令行结果大概是这样的,注意核对输出结果中的证书应用是正确的。

 这一步也不要“公证”,公证有可能导致打包的pkg内部出问题,导致在上传到 transporter 时出现其它未知问题(这个问题,我不清楚,听前辈的经验,没错的)。

如果应用的证书不正确,可能是证书安装问题。electron-builder打包时会根据一定规则选择证书,如果证书选择错误,就把无关的证书删除掉。

如果弹出如下框,一般是你的操作系统的登录密码(如果你对该 “登录”钥匙串设置独立密码了,那就是你设置的那个密码)

(5) 上传应用

打开 transporter 应用,如果没有就在 Mac App Store中下载

将dist\mas-universal(你的有可能是dist\mas 目录)目录中的pkg文件上传到 transporter中

上传交付后,大概如下所示

4、常见问题

(1)问题1

去掉 mac下面的 notarize 配置

七、打包mas-dev

这个是包含了deviceid的,即打包好后可以发给目标设置进行测试。好比你有不同版本的macOS操作系统,你可以将他们的uuid收集起来,打包好后,发给他们,以便测试你的软件是否在其它操作系统上正常运行。如果可以正常运行,那么打包的mas上传到应用商店后,也能正常运行的。

八、打包dmg

你也可以打包成dmg格式,这个格式可以发布到你的官网,以便其它人使用。不过这个格式,需要 进行“公证”,否则别人安装时会提示错误。

九、打包zip

zip其实就是把 .app 格式做成一个压缩包,解压后释放出 .app 格式的文件,然后双击直接运行。

注意:在macOS上,.app 格式的其实就是一个文件夹,只是操作系统会把名字以.app结尾的文件夹识别别一个 macOS应用程序而已。

这个格式也需要进行“公证”,否则别人安装时也会提示错误。

其它图片备份

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/264857.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机的工作原理(上)

1. 计算机发展史 计算的需求在人类的历史中是广泛存在的&#xff0c;发展大体经历了从一般计算工具到机械计算机到目前的电子计算机的发展历程。&#xff08;以下是计算机的发展历程&#xff09; 1、公元前2500 年前&#xff0c;算盘已经出现了&#xff1b;除此之外&#xff0c…

Unity protobuf中repeated转C#文件List只读问题

Unity protobuf中repeated转C#文件List只读问题 介绍问题解决方案总结 介绍 工具这里我就不多介绍了&#xff0c;如果有用到ProtoGen工具的可以继续看一下我后面的方法。 问题 如下图所示&#xff0c;我这里随便用了一个.proto文件&#xff0c;看下我这里面的repeated标记的…

大一C语言作业题目1

目录 字符串和字符数组&#xff1f; %s found的变化&#xff1a; 7-1 学生成绩录入及查询 学生成绩表中&#xff0c;一名学生的信息包含如下信息&#xff1a; 学号(11位)、姓名、数学成绩、英语成绩、程序设计成绩、物理成绩。 本题要求编写程序&#xff0c;录入N条学生的…

【Amazon 实验②】使用缓存策略及源请求策略,用于控制边缘缓存的行为及回源行为

文章目录 1. 了解缓存策略和源请求策略1.1 使用缓存键和缓存策略 实验&#xff1a;使用CloudFront缓存策略和缓存键控制缓存行为 接上一篇文章【Amazon 实验①】使用 Amazon CloudFront加速Web内容分发&#xff0c;我们现在了解和配置如何使用缓存策略及源请求策略&#xff0c;…

NativePHP:使用 PHP 构建桌面应用程序

PHP 在我心中占据着特殊的位置。它是我的第一份工作&#xff0c;我记得我在家里花了无数个小时做一些小项目。我非常想用 PHP 创建桌面应用程序&#xff0c;但我从来没有做到过。 现在&#xff0c;感谢 NativePHP&#xff0c;我可以了。 NativePHP 追随 Slack、Discord 和 Tre…

trino-435版本windows下源码编译

一、源码下载地址 https://github.com/trinodb/trino/tags 二、编译环境及工具准备 1、maven &#xff08;1&#xff09;版本&#xff1a;3.6.3 &#xff08;2&#xff09;settings.xml配置 <?xml version"1.0" encoding"UTF-8"?> <settin…

基于Vite+Vue3 给项目引入Axios

基于ViteVue3 给项目引入Axios,方便与后端进行通信。 系列文章指路&#x1f449; 系列文章-基于Vue3创建前端项目并引入、配置常用的库和工具类 文章目录 安装依赖新建src/config/config.js 用于存放常用配置进行简单封装解决跨域问题调用尝试 安装依赖 npm install axios …

双向数据绑定是什么

一、什么是双向绑定 我们先从单向绑定切入单向绑定非常简单&#xff0c;就是把Model绑定到View&#xff0c;当我们用JavaScript代码更新Model时&#xff0c;View就会自动更新双向绑定就很容易联想到了&#xff0c;在单向绑定的基础上&#xff0c;用户更新了View&#xff0c;Mo…

SuperMap iServer发布的ArcGIS REST 地图服务如何通过ArcGIS API加载

作者&#xff1a;yx 文章目录 一、发布服务二、代码加载三、结果展示 一、发布服务 SuperMap iServer支持将地图发布为ArcGIS REST地图服务&#xff0c;您可以在发布服务时直接勾选ArcGIS REST地图服务&#xff0c;如下图所示&#xff1a; 也可以在已发布的地图服务中&#x…

linux分辨率添加

手动添加分辨率 注&#xff1a;添加分辨率需要显卡驱动支持&#xff0c;若显卡驱动有问题&#xff0c;则不能添加 可通过 xrandr 结果判断 # xrandr 若图中第二行” eDP“ 显示为 ” default “ &#xff0c;则显卡驱动加载失败&#xff0c;不能添加分辨率 1. 添加分辨率 # …

PHP下载安装以及基本配置

目录 引言 官网 下载 配置 1. 鼠标右键“此电脑”>“属性” 2. 打开高级系统设置 3. 打开环境变量 4. 双击系统变量中的path 5. 新建新的path 6. 将刚刚安装的位置加入环境变量 7. 检查是否安装成功 引言 PHP&#xff08;"PHP: Hypertext Preprocessor"…

零基础学C语言——数组

这是一个C语言系列文章&#xff0c;如果是初学者的话&#xff0c;建议先行阅读之前的文章。笔者也会按照章节顺序发布。 上一篇我们讨论过函数&#xff0c;其中涉及到了一些数组和指针&#xff0c;本篇详细说明数组。 数组定义 **数组是一种集合结构&#xff0c;与数学种谈到…

电脑完全重装教程——原版系统镜像安装

注意事项 本教程会清除所有个人文件 请谨慎操作 请谨慎操作 请谨慎操作 前言 本教程是以系统安装U盘为介质进行系统重装操作&#xff0c;照着流程操作会清除整个硬盘里的文件&#xff0c;请考虑清楚哦&#xff5e; 有些小伙伴可能随便在百度上找个WinPE作为启动盘就直接…

前端性能优化六:css阻塞

1. css加载会阻塞DOM树的解析和渲染吗? (1). html代码: <!DOCTYPE html> <html lang"en"><head><style>h1 {color: red !important}</style><script>function h () {console.log(document.querySelectorAll(h1))}setTimeout(…

Leetcode—445.两数相加II【中等】

2023每日刷题&#xff08;六十七&#xff09; Leetcode—445.两数相加II 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2…

[每周一更]-(第38期):Go常见的操作消息队列

在Go语言中&#xff0c;常见的消息队列有以下几种&#xff1a; RabbitMQ&#xff1a;RabbitMQ是一个开源的AMQP&#xff08;高级消息队列协议&#xff09;消息代理软件&#xff0c;用于支持多种编程语言&#xff0c;包括Go语言。RabbitMQ提供了可靠的消息传递机制和灵活的路由…

开源 AI 新秀崛起:Bittensor 更像是真正的“OpenAI”

强大的人工智能正在飞速发展&#xff0c;而完全由 OpenAI、Midjourney、Google&#xff08;Bard&#xff09;这样的少数公司控制 AI 不免让人感到担忧。在这样的背景下&#xff0c;试图用创新性解决方案处理人工智能中心化问题、权力集中于少数公司的 Bittensor&#xff0c;可谓…

让生活更智能,P1600边缘智能网关带你进入智能家居新时代

一、什么是P1600边缘智能网关&#xff1f; 在科技日新月异的今天&#xff0c;我们的生活已经被各种智能产品所包围。而在这个智能化的浪潮中&#xff0c;P1600边缘智能网关以其独特的优势&#xff0c;成为了智能家居的重要组成部分。那么&#xff0c;什么是P1600边缘智能网关呢…

力扣每日一题day38[106. 从中序与后序遍历序列构造二叉树]

给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postorder [9,15,7,20,3] 输出&#xff1a;[…

【数据结构之顺序表】

数据结构学习笔记---002 数据结构之顺序表1、介绍线性表1.1、什么是线性表? 2、什么是顺序表?2.1、概念及结构2.2、顺序表的分类 3、顺序表接口的实现3.1、顺序表动态存储结构的Seqlist.h3.1.1、定义顺序表的动态存储结构3.1.2、声明顺序表各个接口的函数 3.2、顺序表动态存储…