Electron使用指南——Main Process API_mainwindow

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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')



### 一、网安学习成长路线图


网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/aa7be04dc8684d7ea43acc0151aebbf1.png)


### 二、网安视频合集


观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f0aeee2eec7a48f4ad7d083932cb095d.png)


### 三、精品网安学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/078ea1d4cda342f496f9276a4cda5fcf.png)


### 四、网络安全源码合集+工具包

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。  
 **需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)**

![在这里插入图片描述](https://img-blog.csdnimg.cn/e54c0bac8f3049928b488dc1e5080fc5.png)


### 五、网络安全面试题


最后就是大家最关心的网络安全面试题板块  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/15c1192cad414044b4dd41f3df44433d.png)![在这里插入图片描述](https://img-blog.csdnimg.cn/b07abbfab1fd4edc800d7db3eabb956e.png)  



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

在React项目中使用Electron的`ipc`模块,可以通过`electron`模块的`remote`对象访问Electron的主进程。以下是示例代码: 在Electron的主进程中: ```javascript const { ipcMain, BrowserWindow } = require('electron'); let mainWindow; function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }); mainWindow.loadFile('index.html'); mainWindow.on('closed', () => { mainWindow = null; }); } ipcMain.on('message-from-renderer', (event, arg) => { console.log(arg); // 输出来自渲染进程的消息 event.reply('message-from-main', 'Hello from main process!'); // 发送回复消息到渲染进程 }); createWindow(); ``` 在React组件中: ```javascript import React, { useState, useEffect } from 'react'; import { ipcRenderer, remote } from 'electron'; function MyComponent() { const [message, setMessage] = useState(''); useEffect(() => { ipcRenderer.on('message-from-main', (event, arg) => { setMessage(arg); // 接收来自主进程的消息 }); return () => { ipcRenderer.removeAllListeners('message-from-main'); // 移除事件监听器 }; }, []); const handleClick = () => { ipcRenderer.send('message-from-renderer', 'Hello from renderer process!'); // 发送消息到主进程 }; return ( <div> <button onClick={handleClick}>发送消息到主进程</button> {message && <p>收到来自主进程的消息:{message}</p>} </div> ); } ``` 在上面的代码中,我们在React组件中使用`ipcRenderer`对象发送消息到Electron的主进程,并接收来自主进程的回复消息。注意,要在React组件中使用Electron的`remote`模块,需要在开发环境中启动Electron
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值