官网: https://www.electronjs.org/
文档:https://www.electronjs.org/zh/docs/latest/
Electron = Chromium + Node.js + Native API
npm
包来完成开发需求。#项目内安装
npm install electron --save-dev
# 全局安装:
npm install -g electron
这个如果安装失败,可以多安装两遍,也可以使用cnpm来进行安装。
新建一个文件夹,比如叫ElectronDemo01
.
在项目的根目录中新建一个index.html
文件,然后编写如下的代码(可以用快速生成的方式来写这段代码)。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
Hello World!
body>
html>
在根目录下新建一个main.js文件,这个就是Electron的主进程文件。
var electron = require('electron') //引入electron模块
var app = electron.app // 创建electron引用
var BrowserWindow = electron.BrowserWindow; //创建窗口引用
var mainWindow = null ; //声明要打开的主窗口
app.on('ready',()=>{
mainWindow = new BrowserWindow({width:400,height:400}) //设置打开的窗口大小
mainWindow.loadFile('index.html') //加载那个页面
//监听关闭事件,把主窗口设置为null
mainWindow.on('closed',()=>{
mainWindow = null
})
})
写完后直接使用npm init --yes
来初始化package.json文件,文件生成后如下:
{
"name": "ElectronDemo1",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
这时候main
的值为main.js
就正确了。这时候就可以打开终端,在终端里输入electron .
就可以打开窗口了。
若是在创建项目的时候就生成json文件,main对应的会是index.js,但是现在的话会生成main.js
运行:
electron.cmd .
# 注意,后面有一个 .
main.js
我们可以理解package.json
中定义的入口文件就是主进程,那一般一个程序只有一个主进程,而我们可以利用一个主进程,打开多个子窗口.
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它自己的渲染进程中,也就是我们说的渲染进程.
也就是说主进程控制渲染进程,一个主进程可以控制多个渲染进程.
在项目根目录下建立一个xiaojiejie.txt
的文件,然后写入几个小姐姐的名字.
代码如下:
1.麻里梨夏
2.星野娜美
3.高桥圣子
因为要使用node里的fs
模块,所以在设置窗口时,增加全量使用node.js.
var electron = require('electron')
var app = electron.app
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null ;
app.on('ready',()=>{
mainWindow = new BrowserWindow({
width:500,
height:500,
webPreferences:{ nodeIntegration:true} //设置全局使用node.js
})
mainWindow.loadFile('index.html')
mainWindow.on('closed',()=>{
mainWindow = null
})
})
到 新建一个 Electron有主进程和渲染进程,Electron的API方法和模块也是分为可以在主进程和渲染进程中使用.如果想在渲染进程中使用主进程中的模块方法时,可以使用 在 yellow.html 在 然后再打开主进程 绑定快捷键的属性是 例如: 右键菜单的响应事件是写在渲染进程中的,也就是写在 打开 例如 当我们要使用 由于我们已经定义了顶部菜单,没有了打开调试模式的菜单了,这时候可以使用程序来进行打开。在主进程中加入这句代码就可以了。 全部代码如下: 这样就实现了打开窗口,直接进入调试模式,极大的提高了调试效率。 在渲染进程中默认加入一个 如果想使用浏览器打开,我们可以直接在 用BrowserView来嵌入一个网页到应用中,这很类似Web中的 打开根目录下打开 例如: 以前使用过 在 然后打开 在传递消息时,你需要在子窗口的页面中设置一些内容,所以我们不能使用远程的页面,而需要自己建立一个。 在项目根目录,建立一个 先打开 父窗口接收信息需要通过 这样父窗口就可以顺利接收到子串口发送过来的信息了,也可以轻松的显示在子窗口中。 打开文件选择对话框可以使用 桌面客户端的程序都必备的一个功能是判断网络状态,这个其实可以用 其实这个是JavaScript的一种方式进行监听网络状态,监听的事件分别是 新建一个文件,比如叫作 这样我们就完成了基本的网络情况监控,小伙伴们可以在终端中输入 Electron的消息通知是通过 当我们点击一个按钮时,会自动弹出提示消息,告诉我们有新的订单。 新建一个 全局快捷键模块就是 引入后,我们现在的需求是按快捷键 可以使用 因为我们注册的是全局的快捷键,所以当我们关闭软件或者窗口时,记得一定要注销我们的快捷键。防止关闭后打开其他软件和他们的快捷键冲突。 在开发中我们经常会遇到给用户一个激活码,然后让用户复制粘贴的情况,这时候就需要用到 现在要作一个激活码,然后旁边放一个按钮,点击按钮就可以复制这个激活码,你可以把激活码复制到任何地方。 这时候就可以进行预览了,如果提示你的 这个就是允许在Electron中使用 main.js html引入的js 页面调用这个方法即可 当我们使用了Electron开发完应用后,一定想着如何打包成 定位到项目根目录下,然后使用 在工作中我习惯于用yarn来进行安装。安装完成后会在 从代码中可以看出我目前的版本是 第一种打包方法就是直接在命令行中输入 参数说明: 这个命令太长了,每次要是都用这个命令来打包会很烦,所以推荐使用第二种方法: 打开 在项目中新建 使用 参考:index.html
里边写一下界面.这里我们写了一个按钮,然后在按钮下方加一个DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, idivnitial-scale=1.0">
<title>Documenttitle>
head>
<body>
<Button id="btn">小姐姐请进来Button><br/>
<div id="mybaby">div>
<script src="renderer/index.js">script>
body>
html>
renderer
文件夹,在文件里新建index.js
,再index.html页面里先进行引入.
编写index.js
里的代码var fs = require('fs'); //引入node.js(需要在main.js中全局引入:webPreferences:{ nodeIntegration:true})
window.onload = function(){//监听页面
var btn = this.document.querySelector('#btn') //获取按钮
var mybaby = this.document.querySelector('#mybaby') //获取显示的div
btn.onclick = function(){ //点击按钮监听
fs.readFile('xiaojiejie.txt',(err,data)=>{ //读取文件(默认项目根目录)
mybaby.innerHTML = data //赋值
})
}
}
Electron Remote模块的使用
Electron Remote
解决在渲染和主进程间的通讯。
新建一个demo2.html
文件,然后快速生成html的基本结构,编写一个按钮,引入渲染的js页面。DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<Button id="btn">打开新的窗口Button><br/>
<script src="renderer/demo2.js">script>
body>
html>
render
文件夹下,新建一个demo2.js
文件,然后编写如下代码。 const btn = this.document.querySelector('#btn')
const BrowserWindow =require('electron').remote.BrowserWindow
window.onload = function(){
btn.onclick = ()=>{
newWin = new BrowserWindow({
width:500,
height:500,
})
newWin.loadFile('yellow.html')
newWin.on('close',()=>{win=null})
}
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, idivnitial-scale=1.0">
<title>Documenttitle>
head>
<body>
yellow
body>
html>
创建菜单和基本使用
编写菜单模板
Electron
中编写菜单,需要先建立一个模板,这个目标很类似我们JSON
或者类的数组。
我们打开项目,在项目的根目录下新建一个文件夹main
,意思是主进程中用到的代码我们都写到这里。
然后新建一个menu.js
文件,然后编写如下代码。//放所有菜单的操作
const { Menu,BrowserWindow } = require('electron')
//所有的菜单
var template = [
{
label:'凤来怡洗浴会所',//菜单
submenu:[//子菜单
{label:'精品SPA',
click:()=>{ //设置点击事件,使用的是electron的功能
win = new BrowserWindow({//创建新窗口
width:500,
height:500,
webPreferences:{ nodeIntegration:true}
})
win.loadFile('yellow.html')
win.on('closed',()=>{//监听关闭事件
win = null
})
}
},
{label:'泰式按摩'}
]
},
{
label:'大浪淘沙洗浴中心',
submenu:[
{label:'牛奶玫瑰浴'},
{label:'爱情拍拍手'}
]
}
]
//构建菜单模板
var m = Menu.buildFromTemplate(template)
//设置菜单模板
Menu.setApplicationMenu(m)
main.js
文件,在ready
生命周期中,直接加入下面的代码,就可以实现自定义菜单了。 require('./main/menu.js') //在引入页面之前加,比如:
var electron = require('electron') //引入electron模块
var app = electron.app // 创建electron引用
var BrowserWindow = electron.BrowserWindow; //创建窗口引用
var mainWindow = null ; //声明要打开的主窗口
app.on('ready',()=>{
mainWindow = new BrowserWindow({
width:400,height:400,
webPreferences:{ nodeIntegration:true}//全局引用node.js
}) //设置打开的窗口大小
//----------------------
require('./main/menu.js')//引入自定义的菜单
//------------------------
mainWindow.loadFile('demo2.html') //加载那个页面,使用新页面
//监听关闭事件,把主窗口设置为null
mainWindow.on('closed',()=>{
mainWindow = null
})
})
绑定快捷键
accelerator
属性,比如我们新打开一个窗口,我们就的代码可以写成这样。accelerator:`ctrl+n`
const { Menu ,BrowserWindow} = require('electron')
var template = [
{
label:'凤来怡洗浴会所',
submenu:[
{
label:'精品SPA',
accelerator:`ctrl+n`, //设置快捷键
click:()=>{
win = new BrowserWindow({
width:500,
height:500,
webPreferences:{ nodeIntegration:true}
})
win.loadFile('yellow.html')
win.on('closed',()=>{
win = null
})
}
},
{label:'泰式按摩'}
]
},
{
label:'大浪淘沙洗浴中心',
submenu:[
{label:'牛奶玫瑰浴'},
{label:'爱情拍拍手'}
]
}chengxu
]
var m = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(m)
右键菜单
index.html
中的,所以要是使用,就用到到remote
模块进行操作了。render
文件夹,然后打开demo2.js
文件,编写一个右键菜单的监听事件window.addEventListener('contextmenu',function(){
alert(111);
})
const btn = this.document.querySelector('#btn')
const BrowserWindow =require('electron').remote.BrowserWindow //
window.onload = function(){
btn.onclick = ()=>{//点击按钮,打开一个窗口,打开页面
newWin = new BrowserWindow({
width:500,
height:500,
})
newWin.loadFile('yellow.html')
newWin.on('close',()=>{win=null})
}
}
//监听右键点击事件-------------
window.addEventListener('contextmenu',function(){
alert(111);
})
Menu
模块,它是主线中的模块,如果想在渲染线程中使用,就必须使用remote
。//引入remote就可以使用了
const { remote} = require('electron')
//右键的菜单
var rigthTemplate = [
{label:'粘贴',accelerator:`ctrl+c`},//菜单,快捷键
{label:'复制'}
]
//声明菜单
var m = remote.Menu.buildFromTemplate(rigthTemplate)
//监听右键点击事件-------------
window.addEventListener('contextmenu',function(e){
//阻止当前窗口默认事件
e.preventDefault();
//把菜单模板添加到右键菜单,弹出右键菜单
m.popup({window:remote.getCurrentWindow()})
})
打开调试模式
mainWindow.webContents.openDevTools()
var electron = require('electron')
var app = electron.app
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null ;
app.on('ready',()=>{
mainWindow = new BrowserWindow({
width:500,
height:500,
webPreferences:{ nodeIntegration:true}
})
mainWindow.webContents.openDevTools() //打开调试模式
require('./main/menu.js')
mainWindow.loadFile('demo2.html')
mainWindow.on('closed',()=>{
mainWindow = null
})
})
Electron 中使用shell通过链接打开浏览器
标签,进行跳转默认是直接在窗口中打开,而不是在浏览器中打开的,如果我们想在默认浏览器中打开,要使用
electron shell
在浏览器中打开链接。案例:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<h1>
<a href="https://jspang.com">技术胖的博客a>
<a id="aHref" href="https://jspang.com">技术胖的博客a>
h1>
<script src="./renderer/demo3.js">script>
body>
html>
标签中加入id,然后在
render
文件夹下,新建一个demo3.js
文件,先在文件首页中引入shell
,然后编写响应事件click
。var { shell } = require('electron') //需要使用的是shell
var aHref = document.querySelector('#aHref')
aHref.onclick = function(e){
e.preventDefault() //组织默认行为
var href = this.getAttribute('href') //获取连接
shell.openExternal(href) //打开连接
}
Electron 中嵌入网页和打开子窗口
标签。需要注意的是
BrowserView
是主进程中的类,所以只能在主进程中使用。在主进程中用BrowserView嵌入网页
main.js
,直接引入并使用BrowserView
就可以实现键入网页到应用中。var BrowserView = electron.BrowserView //引入BrowserView
var view = new BrowserView() //new出对象
mainWindow.setBrowserView(view) // 在主窗口中设置view可用
view.setBounds({x:0,y:100,width:1200, height:800}) //定义view的具体样式和位置
view.webContents.loadURL('https://jspang.com') //wiew载入的页面
var electron = require('electron') //引入electron模块
var app = electron.app // 创建electron引用
var BrowserWindow = electron.BrowserWindow; //创建窗口引用
var mainWindow = null ; //声明要打开的主窗口
app.on('ready',()=>{
mainWindow = new BrowserWindow({
width:400,height:400,
webPreferences:{ nodeIntegration:true}//全局引用node.js
}) //设置打开的窗口大小
mainWindow.webContents.openDevTools() //打开调试模式
require('./main/menu.js')//引入自定义的菜单
mainWindow.loadFile('demo3.html') //加载那个页面,使用新页面
//---------嵌入网页----------
var BrowserView = electron.BrowserView //引入BrowserView
var view = new BrowserView() //new出对象
mainWindow.setBrowserView(view) // 在主窗口中设置view可用
view.setBounds({x:0,y:100,width:1200, height:800}) //定义view的具体样式和位置
view.webContents.loadURL('https://jspang.com') //wiew载入的页面
//----------------
//监听关闭事件,把主窗口设置为null
mainWindow.on('closed',()=>{
mainWindow = null
})
})
用window.open打开子窗口
BrowserWindow
,这个是有区别的,
通常把window.open
打开的窗口叫做子窗口。
关闭父窗口,会同时关闭子窗口demo3.html
中,加入一个按钮,代码如下: <button id="mybtn" >打开子窗口button>
demo3.js
,先获取button
的DOM节点,然后监听onclick事件,代码如下:var mybtn = document.querySelector('#mybtn')
mybtn.onclick = function(e){
window.open('https://jspang.com')
}
Electron Window.open子窗口和父窗口间的通信
window.opener.postMessage(message,targetOrigin)
,是将消息发送给指定来源的父窗口,如果未指定来源则发送给*
,即所有窗口。
String
类型的值案例
popup_page.html
文件。DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<h2>我是弹出子窗口h2>
<button id="popBtn">向窗口传递信息button>
body>
<script>
var popBtn = this.document.querySelector('#popBtn')
popBtn.onclick = function(e){
//window.opener.postMessage 子窗口向父窗口传递消息
window.opener.postMessage('我是子窗口的消息')
}
script>
html>
父窗口接受消息
demo3.html
,在代码最下面,加一个<div id="mytext">div>
window.addEventListener
,例如现在我们打开demo3.js
,也就是父窗口的JS代码部分,写入下面代码:window.addEventListener('message',(msg)=>{
let mytext = document.querySelector('#mytext')
mytext.innerHTML = JSON.stringify(msg)
})
{"isTrusted":false,"data":"我是子窗口的消息","origin":"file://","source":{"location":{"href":"file:///D:/data/electron/demo01/popup_page.html","hash":"","host":"","hostname":"","origin":"file://","pathname":"/D:/data/electron/demo01/popup_page.html","port":"","protocol":"file:","search":""},"closed":false}}
Electron 选择文件对话框showOpenDialog
dialog.showOpenDialog()
方法来打开,它有两个参数,一个是设置基本属性,另一个是回调函数,如果是异步可以使用then
来实现。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<button id="openBtn">打开文件button>
<img src='' id='images'>
body>
<script>
//引入dialog
const {dialog} = require('electron').remote
var openBtn = document.getElementById('openBtn');
openBtn.onclick = function(){
//打开文件选择对话框
dialog.showOpenDialog({
title:'请选择你喜欢的小姐姐照片' , //弹窗名:左上角
defaultPath:'./img/1.jpg', //默认路径的设置,是一个文件(默认根目录)
filters:[ //过滤器
{name:'只jpg',extensions:['jpg','png']},
{name:'png',extensions:['png']}
],
buttonLabel:'打开图片', //自定义
}).then(result=>{
let image = document.getElementById('images')
image.setAttribute("src",result.filePaths[0]);
console.log(result)
}).catch(err=>{
console.log(err)
})
}
script>
html>
文件保存对话框showSaveDialog
dialog.showSaveDialog()
<button id="saveBtn">保存文件button>
//保存文件
const fs = require('fs') //流处理
var saveBtn = document.getElementById('saveBtn')
saveBtn.onclick = function(){
dialog.showSaveDialog({ //打开保存
title:'保存文件',
}).then(result=>{
console.log(result)
fs.writeFileSync(result.filePath,'技术胖一个前端爱好者')//将字符串写入选择的位置(需要包含文件名)
}).catch(err=>{
console.log(err)
})
}
Electron 消息对话框的操作showMessageBox
showMessageBox 相关属性
none
、info
、error
、question
和warning
案例:制作一个确认对话框
<button id="messageBtn">弹出对话框button>
var messageBtn = document.getElementById('messageBtn')
messageBtn.onclick = function(){
dialog.showMessageBox({
type:'warning',
title:'去不去由你',
message:'是不是要跟胖哥去红袖招?',
buttons:['我要去','不去了']
}).then(result=>{
console.log(result)
})
}
回调中result
里有一个response
这个里会给我们返回按钮的数组下标。Electron 断网提醒功能制作
window.addEventListener
来进行时间监听。online
和offline
。
demo5.html
文件,然后编写下面的代码:DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<h2> JSPang.com 断网提醒测试 h2>
body>
<script>
window.addEventListener('online',function(){
alert('官人,我来了,我们继续哦!')
})
window.addEventListener('offline',function(){
alert('小女子先行离开一会,请稍等!')
})
script>
html>
electron .
预览效果。
Electron 底部通知消息的制作
H5
的window.Notification
来实现的。window.Notification的属性参数
点击按钮提示消息
demo5.html
,然后编写如下代码。 DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<button id="notifyBtn">通知消息button>
body>
<script>
var notifyBtn = document.getElementById('notifyBtn');
var option = {
title:'小二,来订单了,出来接客了!',
body:'有大官人刚翻了你的牌子',
}
notifyBtn.onclick = function(){
new window.Notification(option.title,option)
}
script>
html>
Electron注册全局快捷键
globalShortcut
,意思就是我们打开软件以后,按键盘上的快捷键,就可以实现用快捷键实现特定的功能,相当于用键盘快捷键触发某些事件。注册快捷键
globalShortcut
是主进程中的模块,而且注册的都是全局的快捷键,所以你尽量写在main.js
中。打开main.js
,然后先引入globalShortcut
,代码如下:var globalShortcut = electron.globalShortcut
ctrl+e
键后,打开我的博客https://jspang.com
。这时候使用globalShortcut.register
方法就可以实现.
这里需要注意的是,注册全局的快捷键必须在ready
事件之后,才能注册成功。检测快捷键是否注册成功
globalShortcut.isRegistered()
方法,来检测快捷键是否注册成功,因为你可能同时打开很多软件,它们已经占用了一些快捷键的组合,所以并不是你100%可以注册成功的。如果你在实际开发中,可能当有冲突时,软件是支持可以修改快捷键。注销快捷键
//注销全局快捷键的监听
globalShortcut.unregister('ctrl+e')
//全部注销
globalShortcut.unregisterAll()
案例
var electron = require('electron')
var app = electron.app
var globalShortcut = electron.globalShortcut //全局快捷键
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null ;
app.on('ready',()=>{
mainWindow = new BrowserWindow({width:800,height:600})
globalShortcut.register('ctrl+e',()=>{ //定义全局快捷键
mainWindow.loadURL('https://jspang.com')
})
//检测快捷键是否注册成功
let isRegister= globalShortcut.isRegistered('ctrl+e')?'Register Success':'Register fail'
console.log('------->'+isRegister)
mainWindow.loadFile('test.html')
//监听关闭事件,把主窗口设置为null
mainWindow.on('closed',()=>{
mainWindow = null
})
})
//关闭主窗口的监听
app.on('will-quit',function(){
//注销全局快捷键的监听
globalShortcut.unregister('ctrl+e')
//全部注销
globalShortcut.unregisterAll()
})
Electron 剪贴板事件的使用
clipboard
模块,也就是我们的剪贴板模块。复制激活码功能实现
先新建一个页面demo7.html
,然后在里边先写相关的html代码。再里边放入一个文字的激活码,然后放入一个按钮。
然后编写标签,首先分本获取
标签的DOM,然后再获取
的DOM,然后点击button时,触发事件,把内容复制到剪贴板中。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
head>
<body>
<div>
激活码:<span id="code">jspangcom1234234242span>
<button id="btn">复制激活码button>
div>
<script>
const { clipboard } = require("electron");
const code = document.getElementById("code");
const btn = document.getElementById("btn");
btn.onclick = function () {
//写入剪切板
clipboard.writeText(code.innerHTML);
alert("复制成功");
};
script>
body>
html>
require
没找到,记得在main.js
中加入这句话。mainWindow = new BrowserWindow({
width:800,
height:600,
webPreferences:{ nodeIntegration:true}
})
node
,现在就应该可以了。退出按钮
const {app, BrowserWindow, Menu,ipcMain} = require('electron') //使用app和ipcMain
ipcMain.on('close',()=>{
app.quit()
})
const ipc = require('electron').ipcRenderer
/*关闭程序*/
function closeApp(){
ipc.send('close');
}
Electorn应用打包
exe
文件,打包的方式有很多,甚至根据你使用不同的前端框架,打包方式也会有所不同。这里我们就学习原汁原味的打包方式,用electron-package
打包。安装electron-packager
npm
来安装electron-packager
当然你也可以使用yarn
来进行安装//npm
npm install electron-packager --save-dev
//yarn
yarn add electron-packager --dev
package.json
文件中看到如下代码:"devDependencies": {
"electron-packager": "^14.2.1"
}
14.2.1
第一种打包方法(不建议)
electron-packager
,然后后边跟着6个打包参数,这种方法太难了。electron-packager
第二种打包方法
package.json
文件,在scripts
下添加代码"packager": "electron-packager ./ HelloWorld --all --out ./outApp --overwrite --icon=./app/img/icon/icon.ico"
outAPP
文件夹。npm run-script packager
就可以进行打包了,打包的时间会非常长,而且如果你安装了一些安全软件,还要时刻看着安全软件的禁止操作,如果不小心被禁止掉了,可能会造成打包的失败。