app

控制应用程序的事件生命周期。

进程:主进程

下面的这个例子将会展示如何在最后一个窗口被关闭时退出应用:

const { app } = require("electron");
app.on("window-all-closed", () => {
  app.quit();
});

事件

app对象会发出以下事件:

will-finish-launching

示例
app.on('will-finish-launching',()=>{

})

当应用程序完成基础的启动的时候被触发。
WindowsLinux中, will-finish-launching事件与ready事件是相同的;
macOS中,这个事件相当于NSApplication中的applicationWillFinishLaunching提示。

经过测试,Windows环境下,will-finish-launching会在ready之前触发

ready

示例
interface NotificationResponse {
    /** @param 标识用户所选操作的字符串 */
    actionIdentifier:string;
    /** @param 通知的发送日期 */
    date:number;
    /** @param 发送请求的唯一标识符*/
    identifier:string
    /** @param 一份与通知关联的自定义信息字典。*/
    userInfo:Record<string, any>
    /** @param 用户输入或选择的文本 */
    userText?:string
}

app.on('ready',(event:Event,launchInfo:Record<string,any> | NotificationResponse)=>{

})

Electron完成初始化时,发出一次。
macOS上,如果通过通知中心启动应用程序,launchInfo保存NSUserNotificationuserInfoUNNotificationResponse的信息。
你也可以通过调用app.isReady()来检查该事件是否已被触发,以及通过app.whenReady()得到一个当Electron已初始化后fulfillPromise

window-all-closed

示例
app.on("window-all-closed", () => {
   
});

当所有的窗口都被关闭时触发。
如果你没有监听此事件并且所有窗口都关闭了,默认的行为是控制退出程序;但如果你监听了此事件,你可以控制是否退出程序。
如果用户按下了Cmd + Q,或者开发者调用了app.quit()Electron会首先关闭所有的窗口然后触发will-quit事件,在这种情况下window-all-closed事件不会被触发。

在关闭所有窗口时打开另一个窗体,模拟病毒行为,点关闭是关不掉的
app.on("window-all-closed", () => {
  const mainWindow = new BrowserWindow({
    width: 400,
    height: 400,
    title: "我是病毒",
  });

  mainWindow.webContents.loadURL("https://wsbd/");
});

before-quit

示例
app.on("before-quit", (event:Event) => {
   
});

在程序关闭窗口前发信号。 调用event.preventDefault()将阻止终止应用程序的默认行为。

如果应用程序是通过autoUpdater.quitAndInstall()发起的退出操作,那么before-quit事件会在所有窗口触发close事件并关闭之后才会被触发。

Windows系统中,如果应用程序是由于系统关机、重启或用户注销而关闭,则不会触发该事件。

will-quit

示例
app.on("will-quit", (event:Event) => {
   
});

当所有窗口被关闭后触发,同时应用程序将退出。 调用event.preventDefault()将阻止终止应用程序的默认行为。
关于window-all-closedwill-quit事件之间的差异, 请参见window-all-closed事件的说明。

quit

示例
app.on("quit", (event:Event,exitCode:number) => {
   
});

在应用程序退出时发出。

Windows系统中,如果应用程序是因系统关机、重启或用户注销而被关闭,则不会触发此事件。

跳过macOS部分事件

没有mac电脑玩不了

browser-window-blur

示例
app.on("browser-window-blur", (event:Event,window:BrowserWindow) => {
   
});

browserWindow失去焦点时触发。

browser-window-focus

示例
app.on("browser-window-focus", (event:Event,window:BrowserWindow) => {
   
});

browserWindow获得焦点时触发。

browser-window-created

示例
app.on("browser-window-created", (event:Event,window:BrowserWindow) => {
   
});

当一个新的browserWindow被创建时触发。

web-contents-created

示例
app.on("web-contents-created", (event:Event,webContents:WebContents) => {
   
});

当一个新的webContents被创建时触发。

certificate-error

示例
interface CertificatePrincipal {
    /** @param 通用名 */
    commonName:string;
    /** @param 组织名称 */
    organizations:string[];
    /** @param 组织单位名称 */
    organizationUnits:string[];
    /** @param 地区 */
    locality:string;
    /** @param 州或省 */
    state:string;
    /** @param 国家或地区 */
    country:string;
}

interface Certificate {
    /** @param PEM编码数据 */
    data:string;
    /** @param 发行主体 */
    issuer:CertificatePrincipal;
    /** @param 发行者通用名 */
    issuerName:string;
    /** @param 发行者证书(没有自签名) */
    issuerCert:Certificate; 
    /** @param 委托主体 */
    subject:CertificatePrincipal;
    /** @param 主题的通用名*/
    subjectName:string;
    /** @param 表示十六进制值的字符串。 */
    serialNumber:string;
    /** @param 证书生效的开始日期,以秒表示 */
    validStart:number;
    /** @param 证书失效的结束日期,以秒表示 */
    validExpiry:number;
    /** @param 证书的指纹 */
    fingerprint:string;
}

app.on("certificate-error", (event:Event,webContents:WebContents,url:string,error:string,certificate:Certificate,callback:(isTrusted:boolean)=>void,isMainFrame:boolean) => {
   
});

当对urlcertificate证书验证失败的时候发出。如果需要信任这个证书,你需要阻止默认行为event.preventDefault()并且调用callback(true)

示例
const { app } = require('electron')

app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
  if (url === 'https://github.com') {
    // 校验的逻辑
    event.preventDefault()
    callback(true)
  } else {
    callback(false)
  }
})

select-client-certificate

示例
app.on("select-client-certificate", (event:Event,webContents:WebContents,url:string,certificateList:Certificate[],callback:(certificate?:Certificate)=>void) => {
   
});

当一个客户证书被请求的时候发出。
url指的是请求客户端认证的网页地址,调用callback时需要传入一个证书列表中的证书。
需要通过调用event.preventDefault()来防止应用自动使用第一个证书进行验证。

示例
const { app } = require('electron')

app.on('select-client-certificate', (event, webContents, url, list, callback) => {
  event.preventDefault()
  callback(list[0])
})

login

示例
interface AuthenticationResponseDetails{
    url:URL;
    pid:number;
}

interface AuthInfo{
    isProxy:boolean;
    scheme:string;
    host:string;
    port:Integer;
    realm:string;
}

app.on('login', (event:Event, webContents?:WebContents, authenticationResponseDetails:AuthenticationResponseDetails, authInfo:AuthInfo, callback:(username?:string,password?:string)=>void;) => {
  event.preventDefault()
  callback(list[0])
})

webContents或者Utility进程 想要进行基础验证时触发。
默认行为是取消所有身份验证。 默认行为是取消所有的验证行为,如果需要重写这个行为,你需要用event.preventDefault()来阻止默认行为,并且使用callback(username, password)来验证。

示例
const { app } = require('electron')

app.on('login', (event, webContents, details, authInfo, callback) => {
  event.preventDefault()
  callback('username', 'secret')
})

callback在缺少用户名和密码的时候被调用,身份验证请求将被取消,同时将返回身份验证错误到页面。

gpu-info-update

示例
app.on('gpu-info-update', () => {

})

每当有GPU信息更新时触发。

render-process-gone

示例
export type TReason = 
// 以零为退出代码退出的进程
'clean-exit' | 
// 以非零退出代码退出的进程
'abnormal-exit' | 
// 进程发送一个SIGTERM,否则是被外部杀死的。
'killed' | 
// 进程崩溃
'crashed' | 
// 进程内存不足
'oom' | 
// 进程从未成功启动
'launch-failed' | 
// 窗口代码完整性检查失败
'integrity-failure'

interface RenderProcessGoneDetails {
    /** @param 渲染进程消失的原因。 */
    reason:TReason;
    /** @param 进程的退出代码,除非在 reason 是 launch-failed 的情况下, exitCode 将是一个平台特定的启动失败错误代码。*/
    exitCode:number;
}

app.on('render-process-gone', (event:Event,webContents:WebContents,details:RenderProcessGoneDetails) => {

})

渲染器进程意外消失时触发。
这种情况通常因为进程崩溃或被杀死。

child-process-gone

示例
interface Details{
    /** @param 进程类型。 以下值之一 */
    type: 'Utility'|'Zygote'|'Sandbox helper'|'GPU'|'Pepper Plugin'|'Pepper Plugin Broker'|'Unknown';
    /** @param 子进程结束的原因 */
    reason:TReason;
    /** @param 进程的退出代码(例如,如果在 POSIX 上,则来自 waitpid 的状态,在 Windows 上来自 GetExitCodeProcess) */
    exitCode:number;
    /** @param 进程的非本地化名称 */
    serviceName?:string;
    /** @param 进程的名称 功能性示例: Audio Service, Content Decryption Module Service, Network Service, Video Capture, 等等。 */
    name?:string;
}

app.on('child-process-gone', (event:Event,details:Details) => {

})

子进程意外消失时触发。
这种情况通常因为进程崩溃或被杀死。
子进程不包括渲染器进程。

accessibility-support-changed macOS Windows

示例
app.on('accessibility-support-changed', (
    event:Event,
    // 当开启了Chrome辅助功能支持为true,否则为false
    accessibilitySupportEnabled:boolean
    ) => {

    }
)

Chrome的辅助功能状态改变时触发。
当启用或禁用辅助技术时将触发此事件,例如屏幕阅读器 。
查看更多详情

session-created

示例
app.on('session-created', (session:Session) => {

})

Electron创建了一个新的session后被触发.

second-instance

示例
app.on('second-instance', (
    event:Event,
    // 第二实例命令行参数的数组。
    argv:string[],
    // 第二实例的工作目录
    workingDirectory:string,
    // 第二个实例发送过来的额外的JSON对象
    additionalData:unknown
    ) => {

})

当第二个实例被执行并且调用app.requestSingleInstanceLock()时,这个事件将在你的应用程序的首个实例中触发
argv是第二个实例的命令行参数的数组 workingDirectory是这个实例当前工作目录。
通常, 应用程序会激活窗口并且取消最小化来响应。

argv并不一定与传递给第二个实例的参数列表完全一致。参数的顺序可能会发生变化,也可能会附加额外的参数。 如果需要保持参数完全一致,建议使用additionalData

如果第二个实例是由不同的用户启动的,则argv数组将不会包含传入的参数。

保证在appready事件发出后发出此事件。

Chromium可能会添加额外的命令行参数,例如--original-process-start-time

方法

某些方法仅在特定操作系统上可用,并已作相应标注。

app.quit

示例
app.quit();

尝试关闭所有窗口,将首先发出before-quit事件。
如果所有窗口都已成功关闭, 则将发出will-quit事件, 并且默认情况下应用程序将终止。

此方法会确保执行所有beforeunloadunload事件处理程序。
可以在退出窗口之前的beforeunload事件处理程序中返回false取消退出。

app.exit

示例
app.exit(exitCode?:number);

使用exitCode立即退出。
exitCode默认为0
所有窗口都将立即被关闭,而不询问用户,而且before-quitwill-quit事件也不会被触发。

开发模式下传入exitCode1会在关闭后结束控制台进程

ELIFECYCLE  Command failed with exit code 1.
ERROR: "dev:electron" exited with 1.
ELIFECYCLE  Command failed with exit code 1.

app.relaunch

示例
app.relaunch(options?:{
    args?:string[];
    execPath?:string;
});

在当前实例退出时重新启动应用程序。
默认情况下,新实例将使用与当前实例相同的工作目录和命令行参数。
当指定了args时,args将作为命令行参数传递。
当指定了execPath时,execPath将被执行以重新启动,而不是当前应用程序。

请注意,此方法在执行时并不会退出应用程序。
在调用app.relaunch后,必须调用app.quitapp.exit才能使应用程序重新启动。

当多次调用app.relaunch时,当前实例退出后将启动多个实例。

一个立即重启当前实例并向新实例添加命令行参数的示例
const { app } = require('electron')

app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) })
app.exit(0)

app.isReady

示例
app.isReady() as boolean;

如果Electron已完成初始化返回boolean - true,否则 false 。 另见 app.whenReady()

app.whenReady

示例
app.whenReady() as Promise<void>;

可视为检查app.isReady()的方便选择,假如应用程序尚未就绪,则订阅ready事件。

app.focus

示例
app.focus(option?:{
    /** @param mac-将接收者设为活动应用,即使另一个应用当前处于活动状态。*/
    steal:boolean;
});

Linux上,使第一个可见窗口获得焦点。
macOS上,将应用程序变成激活的app
Windows上,使应用程序的第一个窗口获得焦点。

你应该尽可能少地使用steal选项。

app.hide mac

示例
app.hide();

隐藏所有的应用窗口,不是最小化.

mac专属方法,window调用会直接报错,app.hide is not function

app.isHidden mac

示例
app.isHidden() as boolean;

如果应用的所有窗口都被隐藏(比如在MacOS系统下使用了Command-H快捷键)则为true ,否则返回false