前言

前段时间,我用electron-vue开发了一款跨平台(目前支持Mac和Windows)的免费开源的图床上传应用——PicGo,在开发过程中踩了不少的坑,不仅来自应用的业务逻辑本身,也来自electron本身。在开发这个应用过程中,我学了不少的东西。因为我也是从0开始学习electron,所以很多经历应该也能给初学、想学electron开发的同学们一些启发和指示。故而写一份Electron的开发实战经历,用最贴近实际工程项目开发的角度来阐述。希望能帮助到大家。

预计将会从几篇系列文章或方面来展开:

  1. electron-vue入门
  2. Main进程和Renderer进程的简单开发
  3. 引入基于Lodash的json database——lowdb
  4. 跨平台的一些兼容措施
  5. 通过CI发布以及更新的方式
  6. ...(想到再写)

说明

PicGo是采用electron-vue开发的,所以如果你会vue,那么跟着一起来学习将会比较快。如果你的技术栈是其他的诸如reactangular,那么纯按照本教程虽然在render端(可以理解为页面)的构建可能学习到的东西不多,不过在main端(electron的主进程)应该还是能学习到相应的知识的。

如果之前的文章没阅读的朋友可以先从之前的文章跟着看。

Main进程和Renderer进程的基本认识

从上一篇文章结尾部分我们运行成功的一个electron-vue的DEMO来直观看看这两个进程的粗浅认识:

可以看到Main进程管理的是这个app窗口(BrowserWindow),而Renderer进程负责的就是我们熟悉的页面UI渲染。不过实际上,它们远远不仅如此。下面一张图能够把它们所支持、管理的electron或者原生的模块大致列出来:

图中列出来的大部分模块都是我们会在开发过程中用到的。

它们有各自的模块,也有共有的模块比如clipboard等。还有一部分是Main进程里的模块,不过可以通过remote模块,让renderer进程也能使用。比如Menu比如shell等。

了解一下哪些模块在哪些进程里,哪些模块可以通过remote模块让renderer进程也能使用是有必要的,这样我们后续开发的时候才能正确的使用。

上面的模块可能有些从名字里并不能看出作用是啥,没关系,后续的内容会慢慢涉及。

Main进程开发

上面说到了Main进程一个显著的作用就是创建app的窗口。我们来看看这个是怎么实现的。

import { app, BrowserWindow } from 'electron' // 从electron引入app和BrowserWindowlet mainWindowconst winURL = process.env.NODE_ENV === 'development'? `http://localhost:9080` // 开发模式的话走webpack-dev-server的url: `file://${__dirname}/index.html`function createWindow () { // 创建窗口/*** Initial window options*/mainWindow = new BrowserWindow({height: 563,useContentSize: true,width: 1000}) // 创建一个窗口mainWindow.loadURL(winURL) // 加载窗口的URL -> 来自renderer进程的页面mainWindow.on('closed', () => {mainWindow = null})
}app.on('ready', createWindow) // app准备好的时候创建窗口
复制代码

暂且先不管渲染进程里的页面长什么样,在app准备好的时候打开一个窗口只需要调用一个创建BrowserWindow的方法即可。

main进程里的开发有点当年写jQuery的样子,比较多的是事件驱动型的写法。

app

首先需要注意的是app的模块。这个模块是electron应用的骨架。它掌管着整个应用的生命周期钩子,以及很多其他事件钩子。

app的常用生命周期钩子如下:

  • will-finish-launching 在应用完成基本启动进程之后触发
  • ready 当electron完成初始化后触发
  • window-all-closed 所有窗口都关闭的时候触发,在windows和linux里,所有窗口都退出的时候通常是应用退出的时候
  • before-quit 退出应用之前的时候触发
  • will-quit 即将退出应用的时候触发
  • quit 应用退出的时候触发

而我们通常会在ready的时候执行创建应用窗口、创建应用菜单、创建应用快捷键等初始化操作。而在will-quit或者quit的时候执行一些清空操作,比如解绑应用快捷键。

特别的,在非macOS的系统下,通常一个应用的所有窗口都退出的时候,也是这个应用退出之时。所以可以配合window-all-closed这个钩子来实现:

app.on('window-all-closed', () => {if (process.platform !== 'darwin') { // 当操作系统不是darwin(macOS)的话app.quit() // 退出应用}
})
复制代码

除了上面说的生命周期钩子之外,还有一些常用的事件钩子:

  • active(仅macOS)当应用处于激活状态时
  • browser-window-created 当一个BrowserWindow被创建的时候
  • browser-window-focus 当一个BrowserWindow处于激活状态的时候

这些钩子需要配合一些具体场景来做出具体的操作。比如当一个BrowserWindow处于激活状态的时候修改窗口的title值。

当然,app这个模块除了上述的一些事件钩子之外,还有一些很常用的方法:

  • app.quit() 用于退出应用
  • app.getPath(name) 用于获取一些系统目录,对于存放应用的配置文件等很有用
  • app.focus() 用于激活应用,不同系统激活逻辑不一样

这些事件和方法都是怎么知道的呢?当然是官方文档了。不过并不需要一开始就通读一遍官方的api文档。官方的api文档更多的作用是用来查阅,当你要开发到某个功能的时候再去查它能否有对应的api、怎么使用。

BrowserWindow

BrowserWindow模块用于创建最常见的应用窗口。对于不同系统,创建的窗口的默认样式也不太一样。下面来看看macOS和windows的窗口在外观上的区别:

mac版的

windows版的

可以看到二者在窗口顶部的操作区(最小化、最大化、关闭)和标题的位置以及菜单的位置还是有明显的不同的。它们跟系统原生的窗口是一致的。不过如果你想要美化一下也是没问题的。比如:

mac版的PicGo

和windows的PicGo

其中mac版用了系统的操作区,而windows则没有用系统的操作区,而是用图标模拟的。不过同样的地方是都未使用系统默认的titlebar。这个之后会结合renderer进程来说。

让我们来看看创建一个BrowserWindow的常用配置:

let windowfunction createWindow () {window = new BrowserWindow({height: 900, // 高width: 400, // 宽show: false, // 创建后是否显示frame: false, // 是否创建frameless窗口fullscreenable: false, // 是否允许全屏center: true, // 是否出现在屏幕居中的位置backgroundColor: '#fff' // 背景色,用于transparent和frameless窗口titleBarStyle: 'xxx' // 标题栏的样式,有hidden、hiddenInset、customButtonsOnHover等resizable: false, // 是否允许拉伸大小transparent: true, // 是否是透明窗口(仅macOS)vibrancy: 'ultra-dark', // 窗口模糊的样式(仅macOS)webPreferences: {backgroundThrottling: false // 当页面被置于非激活窗口的时候是否停止动画和计时器}// ... 以及其他可选配置})window.loadURL(url)window.on('closed', () => { window = null })
}
复制代码

窗口的长宽自然不必说,需要指定。其中需要注意的几个比较重要的就是,frame这个选项,默认是true。如果选择了false则会创建一个frameless窗口,创建一个没有顶部工具栏、没有border的窗口。这个也是我们在windows系统下自定义顶部栏的基础。

像上述PicGo的主窗口的配置,就是通过如下的配置实现的:

const createSettingWindow = () => {const options = {height: 450,width: 800,show: false,frame: true,center: true,fullscreenable: false,resizable: false,title: 'PicGo',vibrancy: 'ultra-dark',transparent: true,titleBarStyle: 'hidden',webPreferences: {backgroundThrottling: false}}if (process.platform === 'win32') { // 针对windows平台做出不同的配置options.show = true // 创建即展示options.frame = false // 创建一个frameless窗口options.backgroundColor = '#3f3c37' // 背景色}settingWindow = new BrowserWindow(options)settingWindow.loadURL(settingWinURL)settingWindow.on('closed', () => {settingWindow = null})
}
复制代码

app模块一样,BrowserWindow也有很多常用的事件钩子:

  • closed 当窗口被关闭的时候
  • focus 当窗口被激活的时候
  • show 当窗口展示的时候
  • hide 当窗口被隐藏的时候
  • maxmize 当窗口最大化时
  • minimize 当窗口最小化时
  • ...

当然,也依然有很多实用的方法:

  • BrowserWindow.getFocusedWindow() [静态方法]获取激活的窗口
  • win.close() [实例方法,下同]关闭窗口
  • win.focus() 激活窗口
  • win.show() 显示窗口
  • win.hide() 隐藏窗口
  • win.maximize() 最大化窗口
  • win.minimize() 最小化窗口
  • win.restore() 从最小化窗口恢复
  • ...

针对不同的业务逻辑你需要对窗口进行不一样的操作。这个需要跟你的项目需求相匹配。比如上述说到的,windows的顶部的操作区(放大、缩小、关闭按钮)就可以通过icon模拟+实例方法来实现。

Tray

一开始看这个名字你可能并不知道这个是个什么东西。可以把它理解为不同系统的任务栏里的图标组件吧。

比如在macOS里,Tray配合上图标之后就是顶部栏里的应用图标了:

比如在windows里,Tray配合上图标之后就是windows右下角的应用图标了:

需要注意的是,windows和macOS里,图标的大小都是16*16px。macOS下顶部栏的图标通常都是走黑白路线,所以可以为两种系统分别准备不同的图标。PicGoTray的生成代码大致如下:

function createTray () {const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png`tray = new Tray(menubarPic) // 指定图片的路径// ... 其他代码
}
复制代码

注意上述代码里有一个${__static}的变量。该变量是electron-vue为我们暴露出来的项目根目录下的static文件夹的路径。通过这个路径,在开发和生产阶段都能很好的定位你的静态资源所在的目录。是个很方便的变量。

当然Tray并不只是一个图标而无其他作用了。Tray支持很多有用的事件。其中最关键的两个是clickright-click。分别对应鼠标左键点击和鼠标右键点击事件。

鼠标左键点击事件

  • 在macOS系统下,鼠标左键点击Tray的icon可能会出现配置菜单,也有可能会出现应用窗口。
  • 在windows下,鼠标左键点击Tray的icon通常会出现应用的窗口。

鼠标右键点击事件

  • 在macOS系统下,鼠标右键点击Tray的icon通常会出现配置菜单。
  • 在windows系统下,同上。

所以需要我们去适配不同操作系统下用户的操作习惯。

对应于PicGo而言,在macOS系统下左键点击会出现一个menubar的小窗口,右键点击会出现配置菜单。而在windows下,左键点击会直接出现主窗口,(因为在windows下无小窗口的必要),右键点击会出现配置菜单。它们在PicGo里的实现如下:

function createTray () {const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png`tray = new Tray(menubarPic)const contextMenu = // ...菜单tray.on('right-click', () => { // 右键点击window.hide() // 隐藏小窗口tray.popUpContextMenu(contextMenu) // 打开菜单})tray.on('click', () => { // 左键点击if (process.platform === 'darwin') { // 如果是macOStoggleWindow() // 打开或关闭小窗口} else { // 如果是windowswindow.hide() // 隐藏小窗口if (settingWindow === null) { // 如果主窗口不存在就创建一个createSettingWindow()settingWindow.show()} else { // 如果主窗口在,就显示并激活settingWindow.show()settingWindow.focus()}}})
}
复制代码

对于macOS而言,Tray还有一个很棒的特性——可以拖拽文件到Tray的icon上,会触发如下事件:

  • drop 当任何东西拖拽到icon上时
  • drop-files 当文件被拖拽到icon上时
  • drop-text 当文本被拖拽到icon上时
  • drop-enter 当刚拖拽到icon上时
  • drop-leave 当拖拽事件离开icon时
  • drop-end 当拖拽事件结束时

就像PicGo实现的拖拽图片到Tray的icon上时实现图片上传的功能,就是用到了上述的一些事件:

尤其注意到在拖拽上的时候和拖拽结束后的时候icon是不一样的。在PicGo里是这样实现的,很简单:

  tray.on('drag-enter', () => {tray.setImage(`${__static}/upload.png`)})tray.on('drag-end', () => {tray.setImage(`${__static}/menubar.png`)})
复制代码

Tray另一个重要的作用就是开启菜单项。这个将结合下一节Menu一起说明。

Menu

electron威力强大的Menu组件,既能够生成系统菜单项,也能实现绑定应用常用快捷键的功能。

先来看看什么是系统菜单项:

macOS

windows

主要分两种。

  • 第一种是app的菜单。对于macOS来说就是顶部栏左侧区域的菜单项。对于windows而言就是一个窗口的标题栏下方的菜单区。
  • 第二种是类似于右键菜单的菜单。

第一种菜单可以通过Menu.setApplicationMenu()来实现。

第二种菜单可以通过两个步骤来展示:

1. 创建菜单:

 const contextMenu = Menu.buildFromTemplate([...])
复制代码

2. 展示菜单:

tray.on('right-click', () => { // 右键点击tray的时候tray.popUpContextMenu(contextMenu) // 弹出菜单
})
复制代码

这里我们只介绍了Menu本身。其实组成Menu的是一个一个的MenuItem。它们有很多类型:

  1. normal
  2. separator
  3. submenu
  4. checkbox
  5. radio

以及很多角色:

  1. quit
  2. copy
  3. redo
  4. undo
  5. minimize
  6. close
  7. reload
  8. ...

通常来说,配置的菜单项基本从类型里来组合。比如PicGo的菜单项:

这里面就有normal、submenu、checkbox和radio四种类型。其中默认是normal。

角色的话通常对应的是一些常见的行为。比如quit是退出app,比如minimize是最小化,比如copy是复制。不过需要注意的是,如果你没有在创建app菜单里指定这些操作的快捷键的话,那么一些常见的快捷操作就无法在你的app里使用了。比如ctrl+c或者command+c复制这个操作,如果你没有通过Menu.setApplicationMenu()来设定这个快捷键的话,那么在你的electron应用里就无法执行复制的操作了。PicGo在早期版本里也犯了这个错误。当时的问题是我在开发模式下是没有问题的,但是在生产模式下就无法进行复制粘贴操作。后来查了一下原因,发现原来在开发模式下,electron会置入默认的一些快捷操作菜单,如图:

所以在生产模式如果我没有置入这些快捷键的话,使用者就无法使用了。这个是大坑

说了这么多,来看看生成app的菜单的代码长啥样:

注意,如果在开发模式下直接只使用如下快捷键的话,一些调试快捷键比如F12或者command+shift+i打开控制台的操作就无法使用了。所以在开发模式下不需要创建这些快捷键菜单。

const createMenu = () => {if (process.env.NODE_ENV !== 'development') {const template = [{label: 'Edit',submenu: [{ label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },{ label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },{ type: 'separator' },{ label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },{ label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },{ label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },{ label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' },{label: 'Quit',accelerator: 'CmdOrCtrl+Q',click () {app.quit()}}]}]menu = Menu.buildFromTemplate(template)Menu.setApplicationMenu(menu)}
}
复制代码

可以通过accelerator指定你想要的快捷键。诸如ShiftCtrlCmd等键位缩写。如果是组合键,就加上+。尤其注意到,因为macOS和windows键位的差异,所以有一个很好用的键位缩写CmdOrCtrl,即如果是在macOS上就是Cmd,在windows上就是Ctrl

然后再来看看Tray的“右键”菜单的生成:

 const contextMenu = Menu.buildFromTemplate([{label: '关于',click () {dialog.showMessageBox({title: 'PicGo',message: 'PicGo',detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`})}},{label: '打开详细窗口',click () {if (settingWindow === null) {createSettingWindow()settingWindow.show()} else {settingWindow.show()settingWindow.focus()}}},{label: '选择默认图床',type: 'submenu',submenu: [{label: '微博图床',type: 'radio',checked: db.read().get('picBed.current').value() === 'weibo',click () {db.read().set('picBed.current', 'weibo').write()}},{label: '七牛图床',type: 'radio',checked: db.read().get('picBed.current').value() === 'qiniu',click () {db.read().set('picBed.current', 'qiniu').write()}},{label: '腾讯云COS',type: 'radio',checked: db.read().get('picBed.current').value() === 'tcyun',click () {db.read().set('picBed.current', 'tcyun').write()}},{label: '又拍云图床',type: 'radio',checked: db.read().get('picBed.current').value() === 'upyun',click () {db.read().set('picBed.current', 'upyun').write()}}]},{label: '打开更新助手',type: 'checkbox',checked: db.get('picBed.showUpdateTip').value(),click () {const value = db.read().get('picBed.showUpdateTip').value()db.read().set('picBed.showUpdateTip', !value).write()}},{role: 'quit',label: '退出'}])tray.on('right-click', () => {tray.popUpContextMenu(contextMenu)})
复制代码

注意,菜单项的点击事件可以直接通过click属性来指定。上面我们是先通过了Menu.buildFromTemplate()这个方法创建了菜单,然后再在右键点击Tray图标的时候将其弹(PopUp)出来。

当然也有其他构建菜单的方法。可以通过Menu实例的append方法来加入Menu Item。如下例:

const menu = new Menu()
menu.append(new MenuItem({ label: 'Cut', accelerator: 'CmdOrCtrl+X' }))
menu.append(new MenuItem({ type: 'separator' })) // 分割线
menu.append(new MenuItem({ label: 'Helper', type: 'checkbox', checked: true }))
复制代码

基本上有了上述的几个基本模块,我们的一个应用的骨架是基本搭建好了,拥有窗口、任务栏应用图标和菜单项。其他的Main进程的模块,并不是必须的,当会用到的时候将在之后的文章里逐步提及。下一节我们将来看renderer进程的开发。

Renderer进程开发

对于electron-vue而言,renderer进程其实大部分就是在写我们平时常写的前端页面罢了。不过相对于平时在浏览器里写的页面,在electron里写页面的时候你还能用到不少非浏览器端的模块,比如fs,比如electron通过remote模块暴露给renderer进程的模块。接下去我们来看看renderer进程有哪些需要注意的地方。

请使用Hash模式

往常我们在写Vue的时候都比较喜欢开启路由的history模式,因为这样在浏览器的地址栏上看起来比较好看——没有hash的#号,就如同请求后端的url一般。然而需要注意的是,history模式需要后端服务器的支持。

可能很多朋友平时开发的时候没有感觉,那是因为vue-cli里在开发模式下启动的webpack-dev-server帮你实现了服务端的history-fallback的特性。所以在实际部署的时候,至少都需要在你的web服务器程序诸如nginxapache等配置相关的规则,让前端路由返回给vue-router去处理。

而electron里也是如此。在开发模式下,由于使用的是webpack-dev-server开启的服务器,所以BrowserWindow加载的是来自于类似``http://localhost:9080这样的地址的页面。而在生产模式下,却是使用的file://的协议,比如file://${__dirname}/index.html`来指定窗口加载的页面。

因此,从上面的表述你也能明白了。假如我有一个子路由地址为child。如果不启用Hash模式,在开发模式下没啥问题,http://localhost:9080/child,但是在生产模式下,file://${__dirname}/index.html/child却是无法匹配的一条路径。因此在electron下,vue-router请不要使用history模式,而使用默认的hash模式。

那么上面的问题就迎刃而解,变为file://${__dirname}/index.html#child即可。

PicGo里加载的页面路由规则如下,从中你也能看出我使用的是hash模式。

const winURL = process.env.NODE_ENV === 'development'? `http://localhost:9080`: `file://${__dirname}/index.html`
const settingWinURL = process.env.NODE_ENV === 'development'? `http://localhost:9080/#setting/upload`: `file://${__dirname}/index.html#setting/upload`
复制代码

实现自己的titlebar

在上面讲BrowserWindow的时候,我说到有时为了应用的美观,并不想让我们的应用窗口采用系统默认的titlebar,而想用自己写的来实现。这样的话就在创建你的BrowserWindow的配置里加上一句

titleBarStyle: 'hidden'
复制代码

这样就行了。然后你就可以自行在renderer进程的页面里模拟一个顶部的titlebar了,比如上面提到的PicGotitlebar的样子。实际上代码也很简单:

<div class="fake-title-bar">PicGo - {{ version }}<div class="handle-bar" v-if="os === 'win32'"> <!-- 如果是windows系统 就加上模拟的操作按钮--><i class="el-icon-minus" @click="minimizeWindow"></i><i class="el-icon-close" @click="closeWindow"></i></div>
</div>
复制代码

然后把这个titlebar的position置顶即可。

不过在平时的使用中,我们要注意,一般我们鼠标按住titlebar的时候是可以拖动窗口的。但是如果我们在不加可拖拽的属性之前,我们自己写的titlebar是不具备这样的特性的。要加上这个特性也很简单:

.fake-title-bar {-webkit-app-region drag
}
复制代码

只需一条CSS,即可让你的titlebar可以拖拽。

不过在windows下,操作区的按钮(缩小、放大、关闭)长按应该是不能拖拽的,所以还需要:

.handle-bar {-webkit-app-region no-drag
}
复制代码

变成no-drag,这样就实现了我们自己生成应用的titlebar了。

drag&drop的避免

通常我们用Chrome的时候,有个特性是比如你往Chrome里拖入一个pdf,它就会自动用内置的pdf阅读器打开。你往Chrome里拖入一张图片,它就会打开这张图片。由于我们的electron应用的BrowserWindow其实内部也是一个浏览器,所以这样的特性依然存在。而这也是很多人没有注意的地方。也就是当你开发完一个electron应用之后,往里拖入一张图片,一个pdf等等,如果不是一个可拖拽区域(比如PicGo的上传区),那么它就不应该打开这张图、这个pdf,而是将其排除在外。

所以我们将在全局监听dragdrop事件,当用户拖入一个文件但是又不是拖入可拖拽区域的时候,应该将其屏蔽掉。因为所有的页面都应该要有这样的特性,所以我写了一个vue的mixin

export default {mounted () {this.disableDragEvent()},methods: {disableDragEvent () {window.addEventListener('dragenter', this.disableDrag, false)window.addEventListener('dragover', this.disableDrag)window.addEventListener('drop', this.disableDrag)},disableDrag (e) {const dropzone = document.getElementById('upload-area') // 这个是可拖拽的上传区if (dropzone === null || !dropzone.contains(e.target)) {e.preventDefault()e.dataTransfer.effectAllowed = 'none'e.dataTransfer.dropEffect = 'none'}}},beforeDestroy () {window.removeEventListener('dragenter', this.disableDrag, false)window.removeEventListener('dragover', this.disableDrag)window.removeEventListener('drop', this.disableDrag)}
}
复制代码

这样在全局引入这个mixin即可。

remote模块的使用

remote模块是electron为了让一些原本在Main进程里运行的模块也能在renderer进程里运行而创建的。以下说几个我们会用到的。

electron-vue里内置了vue-electron这个模块,可以在vue里很方便的使用诸如this.$electron.remote.xxx来使用remote的模块。

shell

shell模块的官方说明是:Manage files and URLs using their default applications.也就是使用文件或者URL的默认应用。通常我们可以用其让默认图片应用打开一张图片、让默认浏览器打开一个url。

如果我们想在renderer进程里点击一个按钮然后在默认浏览器里打开一个url的话就可以这样:

<button @click="openURL"></button><script>export default {methods: {openURL () {this.$electron.remote.shell.openExternal('https://github.com/Molunerfinn/PicGo')}}}
</script>
复制代码

是不是很方便?

更多详细的shell的用法可以参考文档。

dialog

有的时候我们会有打开原生的对话框的需求。比如PicGo的版本信息:

macOS

windows

这个时候就可以通过dialog这个模块来实现了。逻辑跟上面一样也是点击一个按钮打开一个dialog:

openDialog () {this.$electron.remote.dialog.showMessageBox({title: 'PicGo',message: 'PicGo',detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo`})
}
复制代码

更多详细的dialog的用法可以参考文档。

Menu和BrowserWindow的应用

使用Menu可能很多人能够理解。但是为什么要使用BrowserWindow呢?因为需要定位你打开Menu的窗口。

在PicGo里,有一个点击按钮打开Menu的操作,大致如下:

buildMenu () {const template = [...]this.menu = Menu.buildFromTemplate(template)},openDialog () {this.menu.popup(remote.getCurrentWindow) // 获取当前打开Menu的窗口}
复制代码

这里的menu.popup就需要你指定一下打开这个menu的窗口。它将自动定位你点击的位置而弹出。

main进程和renderer进程的通信

在Vue里,如果是非父子组件通信,很常用的是通过Bus Event来实现的。而electron里的不同进程间的通信其实也很类似,是通过ipcMainipcRenderer来实现的。其中ipcMain是在main进程里使用的,而ipcRenderer是在renderer进程里使用的。

ipcMain和ipcRenderer

官网的例子其实很简洁明了了,我放出来:

// In main process.
const {ipcMain} = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {console.log(arg)  // prints "ping"event.sender.send('asynchronous-reply', 'pong')
})ipcMain.on('synchronous-message', (event, arg) => {console.log(arg)  // prints "ping"event.returnValue = 'pong'
})
复制代码
// In renderer process (web page).
const {ipcRenderer} = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"ipcRenderer.on('asynchronous-reply', (event, arg) => {console.log(arg) // prints "pong"
})
ipcRenderer.send('asynchronous-message', 'ping')
复制代码

其中ipcMain只有监听来自ipcRenderer的某个事件后才能返回给ipcRenderer值。而ipcRenderer既可以收,也可以发。

那么问题就来了,如何让ipcMain主动发送消息呢?或者说让main进程主动发送消息给ipcRenderer

首先要明确的是,ipcMain无法主动发消息给ipcRenderer。因为ipcMain只有.on()方法没有.send()的方法。所以只能用其他方法来实现。有办法么?有的,用webContents

webContents

webContents其实是BrowserWindow实例的一个属性。也就是如果我们需要在main进程里给某个窗口某个页面发送消息,则必须通过win.webContents.send()方法来发送。

代码大致如下:

// In main process
let win = new BrowserWindow({...})
win.webContents.send('img-files', imgs)
复制代码
// In renderer process
ipcRenderer.on('img-files', (event, files) => {console.log(files)
})
复制代码

所以必须指定要发送的窗口,才能将信息准确送达。

总结

本文详细地讲述了electron里Main进程和Renderer进程的基础知识和开发相关。很多都是我在开发PicGo的时候碰到的问题、踩的坑。也许文中简单的几句话背后就是我无数次的查阅和调试。内容相比第一篇多了不少,希望这篇文章能够给你的electron-vue开发带来一些启发。文中相关的代码,你都可以在PicGo的项目仓库里找到,欢迎点个star~希望本文能够给你带来帮助,这是我最开心的地方。如果喜欢,欢迎关注我的博客以及本系列文章的后续进展。

注:文中的图片除未特地说明之外均属于我个人作品,需要转载请私信

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. PathMatchingResourcePatternResolver 获取资源路径

    //获取路径资源 匹配PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();resolver.getResources("classpath:mapper/*.xml")...

    2024/4/14 21:14:51
  2. 初探Mozilla Fennec —— 历史和现状

    Mozilla Firefox自2004年11月9日发布1.0版本以来,凭借不断改善的用户体验和成功的市场推广赢得了越来越多的用户,截止2009年1月,已经在桌面浏览器市场达到了21.53%的份额。(微软IE的市场份额尽管连续7个月下降,但依然依靠系统捆绑保有高达67.55%的份额,苹果Safari为8.29%…...

    2024/4/18 23:10:11
  3. MySql SqlServer Oracle三者的区别?

    对于程序开发人员而言,目前使用最流行的两种后台数据库即为MySQL和SQLServer。这两者最基本的相似之处在于数据存储和属于查询系统。你可以使用sql来访问这两种数据库的数据,因为它们都支持ansi-sql。 还有,这两种数据库系统都支持二进制关键词和关键索引,这就大大地加快了…...

    2024/4/14 21:14:49
  4. Hibernate3.5.5中 java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanR

    java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()Z 的解决方式 Caused by: java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()Z at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java…...

    2024/4/20 17:14:53
  5. React对static的支持

    在使用ES6编写React组件的时候,你会发现es6支持的static defaultProps = {autoPlay: false,maxLoops: 10, }; static propTypes = {autoPlay: React.PropTypes.bool.isRequired,maxLoops: React.PropTypes.number.isRequired }; 会报错,因为static本是es7中的草案,要想使用s…...

    2024/4/17 12:38:30
  6. swipeListView.getContext().getResources().getInteger

    swipeListView.getContext().getResources().getIntegerandroid工程编译成功后,会自动生成一个R.java文件,类似于string.xml里的<string>项都会在在这个文件中有一个Integer类型,程序会根据这个值最终找到对应string.xml里的哪个<string>项...

    2024/4/14 21:14:47
  7. electron-vue跨平台桌面应用开发实战教程(八)——edgejs调用C# dll

    本文来介绍下怎么使用electron-edge-js来调用C#动态链接库,由于是调用C#动态链接库,所以也只能在windows平台上使用,这一点需要注意在开始之前,同样需要安装node-gyp和windows-build-tools,具体安装方法请参照上一篇 1.安装electron-edge-js npm install electron-edge-js…...

    2024/4/14 21:14:45
  8. SQL--数据库性能优化详解

    出处:https://www.cnblogs.com/easypass/archive/2010/12/08/1900127.html1.数据库访问优化法则要正确的优化SQL,我们需要快速定位能性的瓶颈点,也就是说快速找到我们SQL主要的开销在哪里?而大多数情况性能最慢的设备会是瓶颈点,如下载时网络速度可能会是瓶颈点,本地复制…...

    2024/4/14 21:14:44
  9. C语言static的使用

    static作用(修饰函数、局部变量、全局变量)在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。(1)先来介绍它的第一条也是最重要的一条:隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例…...

    2024/4/14 21:14:43
  10. 第4章 网络信息资源检索

    1 1 第4章 网络信息资源检索 4.1 概述 4.2 网络检索工具—搜索引擎 4.3 综合性搜索引擎 4.4 专业性搜索引擎 4.5 特色搜索引擎 2 4.1.1 网络信息资源的定义、特点 定义: • 从字面上理解,网络信息资源是指“通过计算机 网络可以利用的各种信息资源的总和”。具体的 说是指所…...

    2024/4/17 13:14:32
  11. 前端学习之路Electron——安装

    使用Electron开发的案例: vscode、atom、slack、wordpress 等等 Electron生态 Electron技术可以降低开发PC端的成本和难度。 Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库。 Electron通过将Chromium和Node.js合并到同一个运行时环境…...

    2024/4/15 4:25:37
  12. JPA一对多级联更新遇到的问题

    1、更新的同时删除多的一方的旧数据public class ApplyObject {@OneToMany(cascade=CascadeType.ALL,mappedBy="applyObject",orphanRemoval = true)private List<ApplyObjectList> applyObjectObject;//物品列表 }public class ApplyObjectList {@JoinColumn(…...

    2024/3/13 22:26:57
  13. getResources().getColor(R.color.color_name) is deprecated和drawableTop

    textView.setTextColor(Color.parseColor("#FFFFFF")); //或者 ContextCompat.getColor(context, R.color.color_name)在获取颜色时如果使用getResources().getColor(R.color.color_name) 报错“is deprecated”,使用上面的代码替换。...

    2024/4/15 4:25:47
  14. Android使用getIdentifier()获取资源Id

    使用getIdentifier()方法可以方便的获各应用包下的指定资源ID。方式一 int indentify = getResources().getIdentifier(“com.test.demo:drawable/icon”,null,null);第一个参数格式是:包名 + : +资源文件夹名 + / +资源名;是这种格式 然后其他的可以为null 方式二 intinde…...

    2024/4/15 4:26:07
  15. Java持久化API常见错误

    API 本身,定义在 javax.persistence 包内 问题1: 代码: @OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER, orphanRemoval = true)@JoinColumns({@JoinColumn(name ="equipmentTemplateId", referencedColumnName="equipmentTemplateId&quo…...

    2024/4/15 4:25:37
  16. Electron开发实战之06-vue

    源码 j、源码 j-step-c6bashyarn add vue electron-webpack-vue -Drenderer/index.jsimport Vue from vuenew Vue({render: h => h(h1, Hello World) }).$mount(#app)bashyarn dev...

    2024/4/15 4:25:42
  17. www.1188.com劫持IE,baidu工具条不甘落后

    一位朋友说他的电脑出了问题:◆IE首页设置为空白页,但打开时却显示hxxp://www.1188.com/?y6  ◆桌面上冒出两个IE浏览器的快捷方式,无法删除。  ◆莫名其妙多出了Coopen播放器请偶通过QQ远程协助帮助处理。这种情况最近遇到几次了,还是记录一下罢。使用pe_xscan 扫描 …...

    2024/4/24 10:35:06
  18. Android 中BitmapFactory.decodeResource方法参数个代表什么意思

    BitmapFactory.decodeResource(?,?)这个带两个参数的方法:第一个参数是包含你要加载的位图资源文件的对象(一般写成 getResources()就ok了);第二个时你需要加载的位图资源的Id。 BitmapFactory.decodeResource(?,?,?)带三个参数的方法:前两个和上面的方法一…...

    2024/4/15 4:25:57
  19. JPA中@OneToMany映射

    1、one方获得维护权,many方提供数据 one方注解@OneToMany(cascade = CascadeType.ALL,orphanRemoval=true)@JoinColumn(name="ruleTemplet")private List<ProductCheckRuleCategory> ruleCategoryList = new ArrayList<>();其中cascade = CascadeType.A…...

    2024/4/15 4:26:02
  20. electron中使用sqlite3的安装教程

    1、设置npm的registry地址npm config set registry https://registry.npm.taobao.org查看是否成功npm config get registry2、设置成功后,安装依赖npm install node-gyp --gnpm install --vs2015 -g windows-build-toolsPS:安装python2.7 需要添加path环境变量3、在自己的elec…...

    2024/4/15 4:25:37

最新文章

  1. 华为OD机试真题-模拟目录管理-2024年OD统一考试(C卷D卷)

    题目描述: 实现一个模拟目录管理功能的软件,输入一个命令序列,输出最后一条命令运行结果。 支持命令: 1)创建目录命令:mkdir 目录名称,如mkdir abc为在当前目录创建abc目录,如果已存在同名目录则不执行任何操作。此命令无输出。 2)进入目录命令:cd 目录名称, 如cd …...

    2024/4/24 17:16:06
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Topaz Video AI for Mac v5.0.0激活版 视频画质增强软件

    Topaz Video AI for Mac是一款功能强大的视频处理软件&#xff0c;专为Mac用户设计&#xff0c;旨在通过人工智能技术为视频编辑和增强提供卓越的功能。这款软件利用先进的算法和深度学习技术&#xff0c;能够自动识别和分析视频中的各个元素&#xff0c;并进行智能修复和增强&…...

    2024/4/22 12:34:50
  4. 整理的微信小程序日历(单选/多选/筛选)

    一、日历横向多选&#xff0c;支持单日、双日、三日、工作日等选择 效果图 wxml文件 <view class"calendar"><view class"section"><view class"title flex-box"><button bindtap"past">上一页</button&…...

    2024/4/21 18:25:43
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/23 20:58:27
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/23 13:30:22
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/23 13:28:06
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/20 23:26:47
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/23 13:27:44
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/19 11:57:53
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/23 13:29:53
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/23 13:27:22
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/23 13:28:42
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/23 22:01:21
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/23 13:29:23
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/23 13:27:46
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/23 13:47:22
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/19 11:59:23
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/19 11:59:44
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/23 13:28:08
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/24 16:38:05
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/23 13:28:14
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/23 13:27:51
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/23 13:27:19
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57