Electron使ç¨æåââMain Process API
Main Process API
Electron API ï¼Electron API æä¸ç§ï¼
Main Process ï¼ä¸»è¿è¿ç¨ï¼
Renderer Processï¼æ¸²æè¿ç¨ï¼
Share Modulesï¼å ±äº«æ¨¡åï¼
App
äºä»¶
ready:
å½ Electron å®æåå§åæ¶è¢«è§¦åã
- 两ç§ä½¿ç¨æ¹æ³
app.on('ready', createWindow)
app.on('ready', () => {
console.log('App is ready!')
createWindow()
})
- æ£æ¥åºç¨æ¯å¦ç»å½ï¼app.isReady()
- å¦æåºç¨æ²¡æReadyï¼app.isReady()çå¼ä¸º false
console.log('åºç¨æ¯å¦ç»å½ï¼' + app.isReady())
- æ¤æ¶åºç¨åºè¯¥å·²ç»Ready
setTimeout(() => {
console.log('åºç¨æ¯å¦ç»å½ï¼' + app.isReady())
}, 2000)
before-quit
å¨åºç¨ç¨åºå¼å§å ³éçªå£ä¹å触åã
app.on('before-quit', (e) => {
console.log('App is quiting')
e.preventDefault()
})
browser-window-blur
å¨ browserWindow 失å»ç¦ç¹æ¶ååº
app.on('browser-window-blur', (e) => {
console.log('App unfocused')
})
browser-window-focus
å¨ browserWindow è·å¾ç¦ç¹æ¶ååº
app.on('browser-window-focus', (e) => {
console.log('App focused')
})
æ¹æ³
app.quit()
app.on('browser-window-blur', (e) => {
setTimeout(() => {
app.quit()
}, 3000)
})
app.on('browser-window-blur', (e) => {
setTimeout(app.quit, 3000)
})
app.getPath(name)
app.on('ready', () => {
console.log(app.getPath('desktop'))
console.log(app.getPath('music'))
console.log(app.getPath('temp'))
console.log(app.getPath('userData'))
createWindow()
})
BrowserWindow
electron.BrowserWindow: å建åæ§å¶æµè§å¨çªå£
å®ä¾æ¹æ³
win.loadURL(url[, options]): å loadFile äºæ¥
mainWindow.loadURL('https://www.baidu.com')
ä¼é çæ¾ç¤ºçªå£
- 使ç¨ready-to-showäºä»¶
let mainWindow = new BrowserWindow({ show: false })
mainWindow.once('ready-to-show', () => {
mainWindow.show()
})
- 设置 backgroundColor
let win = new BrowserWindow({ backgroundColor: '#2e2c29' })
ç¶åçªå£
- çªå£å®ä¹
secondaryWindow = new BrowserWindow({
width: 600,
height: 600,
webPreferences: { nodeIntegration: true }
})
secondaryWindow.loadFile('index.html')
secondaryWindow.on('closed', () => {
mainWindow = null
})
- çªå£å ³ç³»
secondaryWindow = new BrowserWindow({
parent: mainWindon, // å®ä¹ç¶çªå£
modal: true // éå®å¨ä¸»çªå£
})
- åçªå£æ¾ç¤ºåéè
secondaryWindow = new BrowserWindow({
show: false
})
setTimeout(() => {
secondaryWindow.show()
setTimeout(() => {
secondaryWindow.hide()
}, 3000)
}, 2000)
æ è¾¹æ¡çªå£
Frameless Window
mainWindow = new BrowserWindow({
frame: false
})
让页é¢å¯ææ½
<body style="user-select: none; -webkit-app-region:drag;">
no-drag ä¿®å¤ä¸é¢æ§ä»¶çbug
<input style="-webkit-app-region: no-drag;" type="range" name="range" min="0" max="10">
æ¾ç¤ºçº¢ç»¿ç¯
mainWindow = new BrowserWindow({
titleBarStyle: 'hidden' // or hiddenInset è·ç¦»çº¢ç»¿ç¯æ´è¿
})
å±æ§ä¸æ¹æ³
minWidth && minHeight
mainWindow = new BrowserWindow({
minWidth: 300,
minHeight: 300
})
æ´å¤è¯¦è§ï¼https://electronjs.org/docs/api/browser-window#new-browserwindowoptions
çªå£ç¦ç¹äºä»¶
secWindow = new BrowserWindow({
width: 400, height: 300,
webPreferences: { nodeIntegration: true },
})
mainWindow.on('focus', () => {
console.log('mainWindow focused')
})
secWindow.on('focus', () => {
console.log('secWindow focused')
})
app.on('browser-window-focus', () => {
console.log('App focused')
})
éææ¹æ³
- getAllWindows()
let allWindows = BrowserWindow.getAllWindows()
console.log(allWindows)
æ´å¤è¯¦è§: https://electronjs.org/docs/api/browser-window#%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95
å®ä¾å±æ§
- id
console.log(secWindow.id)
æ´å¤è¯¦è§ï¼https://electronjs.org/docs/api/browser-window#%E5%AE%9E%E4%BE%8B%E5%B1%9E%E6%80%A7
å®ä¾æ¹æ³
- maximize()secWindow.on('closed', () => { mainWindow.maximize() })
æ´å¤è¯¦è§ï¼https://electronjs.org/docs/api/browser-window#%E5%AE%9E%E4%BE%8B%E6%96%B9%E6%B3%95
state
electron-window-state ä¿åçªå£çç¶æ npm install electron-window-state
webContents
webContents æ¯ EventEmitter çå®ä¾ï¼ è´è´£æ¸²æåæ§å¶ç½é¡µ, æ¯ BrowserWindow 对象çä¸ä¸ªå±æ§ã
let wc = mainWindow.webContents console.log(wc)
æ¹æ³ getAllWebContents(ï¼
- è¿å WebContents[] - ææ WebContents å®ä¾çæ°ç»ã å å«ææWindowsï¼webviewsï¼opened devtools å devtools æ©å±èæ¯é¡µç web å 容const {app, BrowserWindow, webContents} = require('electron') console.log(webContents.getAllWebContents())
å®ä¾äºä»¶
- did-finish-load
- dom-ready
<div>
<img src="https://placekitten.com/500/500" alt="">
</div>
<script>
let wc = mainWindow.webContents
wc.on('did-finish-load', () => {
console.log('Conent fully loaded')
})
wc.on('dom-ready', () => {
console.log('DOM Ready')
})
</script>
- new-window
<div>
<a target="_blank" href="https://placekitten.com/500/500"><h3>Kitten</h3></a>
</div>
<script>
wc.on('new-window', (e, url) => {
e.preventDefault()
console.log('DOM Ready')
})
</script>
- before-input-event
wc.on('before-input-event', (e, input) => {
console.log(`${input.key} : ${input.type}`)
})
- login
- did-navigate
mainWindow.loadURL('https://httpbin.org/basic-auth/user/passwd')
wc.on('login', (e, request, authInfo, callback) => {
console.log('Logging in:')
callback('user', 'passwd')
})
wc.on('did-navigate', (e, url, statusCode, message) => {
console.log(`Navigated to: ${url}, with response code: ${statusCode}`)
console.log(message)
})
- media-started-playing
- media-paused
<div>
<video src="./mgm.mp4" controls width="400"></video>
</div>
<script>
wc.on('media-started-playing', () => {
console.log('Video Started')
})
wc.on('media-paused', () => {
console.log('Video Paused')
})
</script>
- context-menu : å³é®ä¸ä¸æä¿¡æ¯
wc.on('context-menu', (e, params) => {
console.log(`Context menu opened on: ${params.mediaType} at x:${params.x}, y:${params.y}`)
})
wc.on('context-menu', (e, params) => {
console.log(`User seleted text: ${params.selectionText}`)
console.log(`Selection can be copied: ${params.editFlags.canCopy}`)
})
å®ä¾æ¹æ³
- executeJavaScript()
wc.on('context-menu', (e, params) => {
wc.executeJavaScript(`alert('${params.selectionText}')`)
})
Session
管çæµè§å¨ä¼è¯ãcookieãç¼åã代ç设置çã
èµ·æ¥
- å建session对象
let session = mainWindow.webContents.session
console.log(session) // {}
- å¨chromium å建localStorageï¼ç¶åå建两个çªå£ï¼ä¸¤ä¸ªsessionå ±äº«
mainWindow = new BrowserWindow({
width: 1000, height: 800,
webPreferences: { nodeIntegration: true }
})
secWindow = new BrowserWindow({
width: 500, height: 400,
webPreferences: { nodeIntegration: true }
})
let session = mainWindow.webContents.session
let session2 = mainWindow.webContents.session
console.log(Object.is(session, session2)) // true
// Load index.html into the new BrowserWindow
mainWindow.loadFile('index.html')
secWindow.loadFile('index.html')
// Open DevTools - Remove for PRODUCTION!
mainWindow.webContents.openDevTools();
secWindow.webContents.openDevTools();
// Listen for window being closed
mainWindow.on('closed', () => {
mainWindow = null
})
secWindow.on('closed', () => {
secWindow = null
})
- defaultSession
const {app, BrowserWindow, session} = require('electron')
let ses = mainWindow.webContents.session
console.log(Object.is(session.defaultSession, ses)) // true
- èªå®ä¹session
let customSes = session.fromPartition('part1')
console.log(Object.is(customSes, ses)) //false, æ¤æ¶customSes è¿æ¯å
񄧮session
secWindow = new BrowserWindow({
width: 500, height: 400,
webPreferences: {
nodeIntegration: true,
session: customSes // å®ä¹session, æ¤æ¶åçªå£æèªå·±çsession
}
})
// å¨åçªå£éå建localstorge: winName/secWindow
// å
³éææçªå£ï¼åç°å建çlocalstorageåæ¶å¤±äºï¼å 为æ¤æ¶çsessionåå¨å¨å
åéï¼éæ°å¯å¨åºç¨åæ¶å¤±äºãå¯ä»¥å åç¼persistï¼ä½¿å
¶å为永ä¹
åå¨ï¼
let customSes = session.fromPartition('persist:part1')
// æè
ï¼
secWindow = new BrowserWindow({
width: 500, height: 400,
webPreferences: {
nodeIntegration: true,
- session: customSes
+ partition: 'persist:part1'
}
})
- å®ä¾æ¹æ³
ses.clearStorageData() // å é¤ä¸»çªå£ççstorage
cookie
æ¥è¯¢åä¿®æ¹ä¸ä¸ªä¼è¯çcookies
// æ¥è¯¢ææ cookies
session.defaultSession.cookies.get({})
.then((cookies) => {
console.log(cookies)
}).catch((error) => {
console.log(error)
})
// æ¥è¯¢ææä¸è®¾ç½®ç URL ç¸å
³çææ cookies
session.defaultSession.cookies.get({ url: 'http://www.github.com' })
.then((cookies) => {
console.log(cookies)
}).catch((error) => {
console.log(error)
})
// 设置ä¸ä¸ª cookieï¼ä½¿ç¨è®¾ç½®çå称ï¼
// å¦æåå¨ï¼åä¼è¦çåå
cookie.
const cookie = { url: 'http://www.github.com', name: 'dummy_name', value: 'dummy' }
session.defaultSession.cookies.set(cookie)
.then(() => {
// success
}, (error) => {
console.error(error)
})
downloadItem
æ§å¶æ¥èªäºè¿ç¨èµæºçæ件ä¸è½½ã
<h2><a href="https://picsum.photos/5000/5000/" download>Download Image</a></h2>
<progress value="0" max="100" id="progress"></progress>
<script>
window.progress = document.getElementById('progress')
</script>
// main.js
let ses = session.defaultSession
ses.on('will-download', (e, downloadItem, webContents) => {
let fileName = downloadItem.getFilename()
let fileSize = downloadItem.getTotalBytes()
// Save to desktop
downloadItem.setSavePath(app.getPath('desktop') + `/${fileName}`)
downloadItem.on('updated', (e, state) => {
let received = downloadItem.getReceivedBytes()
if (state === 'progressing' && received) {
let progress = Math.round((received/fileSize)*100)
webContents.executeJavaScript(`window.progress.value = ${progress}`)
}
})
})
dialog - 对è¯æ¡
æ¾ç¤ºç¨äºæå¼åä¿åæ件ãè¦æ¥ççæ¬æºç³»ç»å¯¹è¯æ¡
const {app, BrowserWindow, dialog} = require('electron')
mainWindow.webContents.on('did-finish-load', () => {
dialog.showOpenDialog({
buttonLabel: 'éæ©',
defaultPath: app.getPath('desktop'),
properties: ['multiSelections', 'createDirectory', 'openFile', 'openDirectory']
}, filepaths => {
console.log(filepaths)
})
})
dialog.showSaveDialog({}, filename => {
console.log(filename)
})
const answers = ['Yes', 'No', 'Maybe']
dialog.showMessageBox({
title: 'Message Box',
message: 'Please select an option',
detail: 'Message details.',
buttons: answers
}, response => {
console.log(`User selected: ${answers[response]}`)
})
å¿«æ·é®+ç³»ç»å¿«æ·é®
å¿«æ·é®ï¼å®ä¹é®çå¿«æ·é®ã ç³»ç»å¿«æ·é®ï¼å¨åºç¨ç¨åºæ²¡æé®çç¦ç¹æ¶ï¼çå¬é®çäºä»¶ã
å¿«æ·é®å¯ä»¥å å«å¤ä¸ªåè½é®åä¸ä¸ªé®ç çå符串ï¼ç±ç¬¦å·+ç»åï¼ç¨æ¥å®ä¹ä½ åºç¨ä¸çé®çå¿«æ·é®
示ä¾ï¼
- CommandOrControl+A
- CommandOrControl+Shift+Z
å¿«æ·æ¹å¼ä½¿ç¨ register æ¹æ³å¨ globalShortcut 模åä¸æ³¨åã
globalShortcut 模åå¯ä»¥å¨æä½ç³»ç»ä¸æ³¨å/注éå ¨å±å¿«æ·é®, 以便å¯ä»¥ä¸ºæä½å®å¶åç§å¿«æ·é®ã
注æ: å¿«æ·æ¹å¼æ¯å ¨å±ç; å³ä½¿åºç¨ç¨åºæ²¡æé®çç¦ç¹, å®ä¹ä»ç¶å¨æç»çå¬é®çäºä»¶ã å¨åºç¨ç¨åºæ¨¡åååº ready äºä»¶ä¹å, ä¸åºä½¿ç¨æ¤æ¨¡åã
const {app, BrowserWindow, globalShortcut} = require('electron')
globalShortcut.register('G', () => {
console.log('User pressed G')
})
globalShortcut.register('CommandOrControl+Y', () => {
console.log('User pressed G with a combination key')
globalShortcut.unregister('CommandOrControl+G')
})
Menu
1ãindex.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<textarea name="name" rows="8" cols="80"></textarea>
<!-- All of the Node.js APIs are available in this renderer process. -->
We are using Node.js <strong><script>document.write( process.versions.node)</script></strong>,
and Electron <strong><script>document.write( process.versions.electron )</script></strong>.
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</body>
</html>
2ãmain.js
// Modules
const {app, BrowserWindow, Menu, MenuItem} = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
let mainMenu = Menu.buildFromTemplate( require('./mainMenu') )
// Create a new BrowserWindow when `app` is ready
function createWindow () {
mainWindow = new BrowserWindow({
width: 1000, height: 800,
webPreferences: { nodeIntegration: true }
})
// Load index.html into the new BrowserWindow
mainWindow.loadFile('index.html')
// Open DevTools - Remove for PRODUCTION!
mainWindow.webContents.openDevTools();
Menu.setApplicationMenu(mainMenu)
// Listen for window being closed
mainWindow.on('closed', () => {
mainWindow = null
})
}
// Electron `app` is ready
app.on('ready', createWindow)
// Quit when all windows are closed - (Not macOS - Darwin)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow
app.on('activate', () => {
if (mainWindow === null) createWindow()
})
3ãmainMenu.js
module.exports = [
{
label: 'Electron',
submenu: [
{ label: 'Item 1'},
{ label: 'Item 2', submenu: [ { label: 'Sub Item 1'} ]},
{ label: 'Item 3'},
]
},
{
label: 'Edit',
submenu: [
{ role: 'undo'},
{ role: 'redo'},
{ role: 'copy'},
{ role: 'paste'},
]
},
{
label: 'Actions',
submenu: [
{
label: 'DevTools',
role: 'toggleDevTools'
},
{
role: 'toggleFullScreen'
},
{
label: 'Greet',
click: () => { console.log('Hello from Main Menu') },
accelerator: 'Shift+Alt+G'
}
]
}
]
Context Menus
1ãindex.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<textarea name="name" rows="8" cols="80"></textarea>
<!-- All of the Node.js APIs are available in this renderer process. -->
We are using Node.js <strong><script>document.write( process.versions.node)</script></strong>,
and Electron <strong><script>document.write( process.versions.electron )</script></strong>.
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</body>
</html>
2ãmain.js
// Modules
const {app, BrowserWindow, Menu} = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
let contextMenu = Menu.buildFromTemplate([
{ label: 'Item 1' },
{ role: 'editMenu' }
])
// Create a new BrowserWindow when `app` is ready
function createWindow () {
mainWindow = new BrowserWindow({
width: 1000, height: 800,
webPreferences: { nodeIntegration: true }
})
// Load index.html into the new BrowserWindow
mainWindow.loadFile('index.html')
// Open DevTools - Remove for PRODUCTION!
mainWindow.webContents.openDevTools();
mainWindow.webContents.on('context-menu', e => {
contextMenu.popup()
})
// Listen for window being closed
mainWindow.on('closed', () => {
mainWindow = null
})
}
// Electron `app` is ready
app.on('ready', createWindow)
// Quit when all windows are closed - (Not macOS - Darwin)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow
app.on('activate', () => {
if (mainWindow === null) createWindow()
})
Tray (æç)
1ãmain.js
// Modules
const {app, BrowserWindow, Tray, Menu} = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow, tray
let trayMenu = Menu.buildFromTemplate([
{ label: 'Item 1' },
{ role: 'quit' }
])
function createTray() {
tray = new Tray('[email protected]')
tray.setToolTip('Tray details')
tray.on('click', e => {
if (e.shiftKey) {
app.quit()
} else {
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show()
}
})
tray.setContextMenu(trayMenu)
}
// Create a new BrowserWindow when `app` is ready
function createWindow () {
createTray()
mainWindow = new BrowserWindow({
width: 1000, height: 800,
webPreferences: { nodeIntegration: true }
})
// Load index.html into the new BrowserWindow
mainWindow.loadFile('index.html')
// Open DevTools - Remove for PRODUCTION!
mainWindow.webContents.openDevTools();
// Listen for window being closed
mainWindow.on('closed', () => {
mainWindow = null
})
}
// Electron `app` is ready
app.on('ready', createWindow)
// Quit when all windows are closed - (Not macOS - Darwin)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow
app.on('activate', () => {
if (mainWindow === null) createWindow()
})
powerMonitor (çµæºæ示å¨)
// Modules
const electron = require('electron')
const {app, BrowserWindow} = electron
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
// Create a new BrowserWindow when `app` is ready
function createWindow () {
mainWindow = new BrowserWindow({
width: 1000, height: 800,
webPreferences: { nodeIntegration: true }
})
// Load index.html into the new BrowserWindow
mainWindow.loadFile('index.html')
// Open DevTools - Remove for PRODUCTION!
mainWindow.webContents.openDevTools();
// Listen for window being closed
mainWindow.on('closed', () => {
mainWindow = null
})
electron.powerMonitor.on('resume', e => {
if(!mainWindow) createWindow()
})
electron.powerMonitor.on('suspend', e => {
console.log('Saving some data')
})
}
// Electron `app` is ready
app.on('ready', createWindow)
// Quit when all windows are closed - (Not macOS - Darwin)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow
app.on('activate', () => {
if (mainWindow === null) createWindow()
})
推荐阅读
-
在安装Python后,运行发现提示api-ms-win-crt-process-l1-1-0.dll丢失怎么解决?
-
electron-vue项目启动&&解决 process is not defined以及带来的Cannot find module ‘axios‘等问题
-
关于electron中入口文件main.js一些重要参数(持续更新maybe)
-
vue-cli4/vue-cil3使用process.env.VUE_APP_BASE_API全局地址代替vue-cli2的process.env.BASE_API
-
Python中if __name__=="__main__" 语句在调用多进程Process过程中的作用分析
-
Electron使ç¨æåââRenderer Process API
-
Electron使ç¨æåââMain Process API
-
Exception in thread “main“ java.lang.NoClassDefFoundError: org/mybatis/generator/api/dom/xml/Element
-
在安装Python后,运行发现提示api-ms-win-crt-process-l1-1-0.dll丢失怎么解决?
-
electron-vue项目启动&&解决 process is not defined以及带来的Cannot find module ‘axios‘等问题