当前位置: 首页 > news >正文

electron基础使用

安装以及运行

当前node版本18+,按照官网提供操作,npm init进行初始化操作,将index.js修改为main.js,执行npm install --save-dev electron。(这里我挂梯子下载成功了。),添加如下代码至package.json

  "scripts": {"start": "electron ."},

新建一个index.html文件,内容随意。新建一个main.js文件,内容如下。主要意思是将一个界面加载到一个应用窗口中。createWindow()方法来将index.html加载进一个新的BrowserWindow实例。在 app 模块的 ready 事件被激发后才能创建浏览器窗口。 可以通过使用 app.whenReady() API来监听此事件。 在whenReady()成功后调用createWindow()函数来打开窗口。

  • app 模块,它控制应用程序的事件生命周期。
  • BrowserWindow 模块,它创建和管理应用程序 窗口。
const { app, BrowserWindow } = require("electron");const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600,});win.loadFile("index.html");
};app.whenReady().then(() => {createWindow();
});

添加关闭应用窗口事件,若输出有乱码则参考该博客输出乱码解决

app.on("window-all-closed", () => {if (process.platform !== "darwin") {console.log("关闭");app.quit();}
});

在这里插入图片描述
添加代码至BrowserWindow中,可以打开控制台操作,应用开启后可以使用ctrl+shift+i打开控制台

    webContents: {openDevTools: true,},

在这里插入图片描述

vue3中运行

基于@quick-start/electron框架快速创建一个基于vue3+electron的项目结构。

npm create @quick-start/electron

最近又新看见一个框架electron-gg地址,感觉挺好的也是基于vue3

预加载脚本

Electron 的主进程是一个拥有着完全操作系统访问权限的 Node.js 环境。 除了 Electron 模组 之外,您也可以访问 Node.js 内置模块 和所有通过 npm 安装的包。 另一方面,出于安全原因,渲染进程默认跑在网页页面上,而并非 Node.js里。

主进程负责管理整个应用程序的生命周期,包含创建窗口,运行在nodejs环境中,每次打开一个窗口,实际是创建一个渲染进程。主进程和渲染进程之间通过IPC通信。

为了将 Electron 的不同类型的进程桥接在一起,我们需要使用被称为 预加载 的特殊脚本。

BrowserWindow 的预加载脚本运行在具有 HTML DOM 和 Node.js、Electron API 的有限子集访问权限的环境中。预加载脚本默认 沙盒化不再拥有完整 Node.js 环境的访问权。 实际上,这意味着你只拥有一个 polyfilled 的 require 函数,这个函数只能访问一组有限的 API。
在这里插入图片描述
预加载脚本在渲染器加载网页之前注入。 如果你想为渲染器添加需要特殊权限的功能,可以通过 contextBridge 接口定义 全局对象。

创建preload.js文件,该脚本通过 versions 这一全局变量,将 Electron 的 process.versions 对象暴露给渲染器。

const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('versions', {node: () => process.versions.node,chrome: () => process.versions.chrome,electron: () => process.versions.electron// 除函数之外,我们也可以暴露变量
})

将脚本附在渲染进程上,在 BrowserWindow 构造器中使用 webPreferences.preload 传入脚本的路径。webPreferences对象是用来定制渲染进程中的特性,其中preload属性是在网页运行其他脚本之前执行的脚本,用来提前注入Nodejs api或者其他需要再渲染进程中运行的脚本。

const { app, BrowserWindow } = require('electron')
const path = require('node:path')const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.join(__dirname, 'preload.js')}})win.loadFile('index.html')
}app.whenReady().then(() => {createWindow()
})

现在渲染器能够全局访问 versions 了,但是还需要将版本等数据渲染到界面中,可以通过window.versions访问,也可以很简单地使用 versions 来访问。 新建一个 renderer.js 脚本, 使用 document.getElementById DOM API 来替换 id 属性为 info 的 HTML 元素的文本。

const information = document.getElementById('info')
information.innerText = `本应用正在使用 Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), 和 Electron (v${versions.electron()})`

然后再index.html文件中引入

  <script src="./renderer.js"></script>

在这里插入图片描述

进程之间通信(简略)

Electron 的主进程和渲染进程有着清楚的分工并且不可互换,无论是从渲染进程直接访问 Node.js 接口,亦或者是从主进程访问 HTML 文档对象模型 (DOM),都是不可能的。
解决这一问题的方法是使用进程间通信 (IPC)。可以使用 Electron 的 ipcMain 模块 ipcRenderer 模块来进行进程间通信。 为了从你的网页向主进程发送消息,你可以使用ipcMain.handle设置一个主进程处理程序(handler),然后在预处理脚本中暴露一个被称为 ipcRenderer.invoke 的函数来触发该处理程序(handler)。

const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("versions", {node: () => process.versions.node,chrome: () => process.versions.chrome,electron: () => process.versions.electron,ping: () => ipcRenderer.invoke("ping"),
});

主进程中设置你的 handle 监听器,在 HTML 文件加载之前完成了这些,所以才能保证在你从渲染器发送 invoke 调用之前处理程序能够准备就绪。
渲染主进程中引入const { app, BrowserWindow, ipcMain } = require("electron");

app.whenReady().then(() => {ipcMain.handle("ping", () => "pong");createWindow();
});

将发送器与接收器设置完成之后,现在你可以将信息通过刚刚定义的 ‘ping’ 通道从渲染器发送至主进程当中。修改renderer中的文件

const func = async () => {const response = await window.versions.ping()console.log(response) // 打印 'pong'
}func()

在这里插入图片描述

打包程序

Electron 的核心模块中没有捆绑任何用于打包或分发文件的工具。 如果您在开发模式下完成了一个 Electron 应用,需要使用额外的工具来打包应用程序 (也称为可分发文件) 并分发给用户 。 可分发文件可以是安装程序 (例如 Windows 上的 MSI) 或者绿色软件 (例如 macOS 上的 .app 文件)。Electron Forge 是一个处理 Electron 应用程序打包与分发的一体化工具。 在工具底层,它将许多现有的 Electron 工具 (例如 @electron/packager、 @electron/osx-sign、electron-winstaller 等) 组合到一起。

安装打包工具npm install --save-dev @electron-forge/cli,然后输入npx electron-forge import等待初始化完毕,之后package会变为如下图所示
在这里插入图片描述

创建一个可分发版本

要创建可分发文件,请使用项目中的 make 脚本,该脚本最终运行了 electron-forge make 命令。npm run make注意如果npm init 的时候,author 与 description 可为任意值,但对于应用打包是必填项。如果没有则会出现如下错误
在这里插入图片描述
注意,项目打包路径中不能包含中文字符,否则报错。 打包成功如下
在这里插入图片描述

  1. npm run make它将首先运行 electron-forge package ,把您的应用程序 代码与 Electron 二进制包结合起来。
  2. 完成打包的代码将会被生成到一个特定的文件夹中。 然后它将使用这个文件夹为每个 maker 配置生成一个可分发文件。
    在这里插入图片描述
    打包完成后查看.exe文件运行。
    在这里插入图片描述

代码签名

为了将桌面应用程序分发给最终用户,我们 强烈建议 您对 Electron 应用进行 代码签名。 代码签名是交付桌面应用程序的重要组成部分,并且它对于应用程序的自动更新功能 (将会在教程最后部分讲解) 来说是必需的。

代码签名是一种可用于证明桌面应用程序是由已知来源创建的安全技术。 Windows 和 macOS 拥有其特定的代码签名系统,这将使用户难以下载或启动未签名的应用程序。代码签名在forge.config.js文件中添加

流程模型

多进程模型:在早期,浏览器通常使用单个进程来处理所有这些功能。 虽然这种模式意味着您打开每个标签页的开销较少,但也同时意味着一个网站的崩溃或无响应会影响到整个浏览器。Chrome 团队决定让每个标签页在自己的进程中渲染, 从而限制了一个网页上的有误或恶意代码可能导致的对整个应用程序造成的伤害。 然后用单个浏览器进程控制这些标签页进程,以及整个应用程序的生命周期。
在这里插入图片描述
electron包含两种进程:主进程和渲染进程。每个 Electron 应用都有一个单一的主进程,作为应用程序的入口点。 主进程在 Node.js 环境中运行,这意味着它具有 require 模块和使用所有 Node.js API 的能力。主进程的主要目的是使用 BrowserWindow 模块创建和管理应用程序窗口。BrowserWindow 类的每个实例创建一个应用程序窗口,且在单独的渲染器进程中加载一个网页。 您可从主进程用 window 的 webContent 对象与网页内容进行交互。

const { BrowserWindow, app } = require("electron");const createWindow = () => {const win = new BrowserWindow({width: 800,height: 800,});win.loadURL("https://github.com"); //网页以地址的形式引入console.log(win.webContents); //主进程中输出
};app.whenReady().then(() => {createWindow();
});

在这里插入图片描述
当一个 BrowserWindow 实例被销毁时,与其相应的渲染器进程也会被终止。

渲染进程:每个 Electron 应用都会为每个打开的 BrowserWindow ( 与每个网页嵌入 ) 生成一个单独的渲染器进程。 洽如其名,渲染器负责 渲染 网页内容。 所以实际上,运行于渲染器进程中的代码是须遵照网页标准的 (至少就目前使用的 Chromium 而言是如此) 。渲染器无权直接访问 require 或其他 Node.js API

Preload 脚本:预加载(preload)脚本包含了那些执行于渲染器进程中,且先于网页内容开始加载的代码 。 这些脚本虽运行于渲染器的环境中,却因能访问 Node.js API 而拥有了更多的权限。预加载脚本可以在 BrowserWindow 构造方法中的 webPreferences .preload选项里被附加到主进程。预加载脚本与浏览器共享同一个全局 Window 接口,并且可以访问 Node.js API,所以它通过在全局 window 中暴露任意 API 来增强渲染器,以便你的网页内容使用。

虽然预加载脚本与其所附着的渲染器在共享着一个全局 window 对象,但您并不能从中直接附加任何变动到 window 之上,因为 contextIsolation 是默认的,因此下面这段代码在窗口的控制台中输出undefined

//preload.js
window.myAPI = {desktop: true
}
//renderer.js
console.log(window.myAPI)
// => undefined

因此需要使用 contextBridge 模块来安全地实现交互.

const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {desktop: true
})

在这里插入图片描述

上下文隔离

上下文隔离功能将确保您的 预加载脚本 和 Electron的内部逻辑 运行在所加载的 webcontent网页 之外的另一个独立的上下文环境里。 这对安全性很重要,因为它有助于阻止网站访问 Electron 的内部组件 和 您的预加载脚本可访问的高等级权限的API

这意味着,实际上,您的预加载脚本访问的 window 对象并不是网站所能访问的对象。 例如,如果您在预加载脚本中设置 window.hello = ‘wave’ 并且启用了上下文隔离,当网站尝试访问window.hello对象时将返回 undefined。

自 Electron 12 以来,默认情况下已启用上下文隔离,并且它是 所有应用程序推荐的安全设置。

其实不使用contextBridge 创建预加载脚本就是没有开启上下文的方式。

进程通信

进程通信的表现形式例如 UI 调用原生 API 或从原生菜单触发 Web 内容的更改。

IPC通道

在 Electron 中,进程使用 ipcMainipcRenderer模块,通过开发人员定义的“通道”传递消息来进行通信。 这些通道是 任意 (您可以随意命名它们)和 双向 (您可以在两个模块中使用相同的通道名称)的。

  1. 渲染器进程到主进程(单向)
    要将单向 IPC 消息从渲染器进程发送到主进程,您可以使用 ipcRenderer.send API 发送消息,然后使用 ipcMain.on API 接收。如下是一个事例,用户输入input内容,点击按钮会修改窗口的标题
index.htmlTitle: <input id="title"/><button id="btn" type="button">Set</button><script src="./renderer.js"></script>
renderer.js
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {const title = titleInput.valuewindow.aaa.setTitle(title) // 渲染主线程使用预加载脚本暴露的通道,使用其提供的方法
})
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("aaa", {//aaa是自定义的通道名//定义一个setTitle函数,通过send方法向主进程发生一个set-title消息,并携带参数setTitle: (title) => ipcRenderer.send("set-title", title), //send方法是一个异步行为
});
main.js
const { BrowserWindow, app, ipcMain } = require("electron");
const path = require("path");function handleSetTitle(e, title) {/* 事件对象 e 中获取发送该事件的 webContents 对象。在 Electron 中,webContents 代表了渲染器进程内的网页内容,每个 Electron 窗口里都有一个与其关联的 webContents 实例*/const webContents = e.sender;/* BrowserWindow.fromWebContents 方法,并传入前面获得的 webContents 对象,可以获取到关联该 webContents 的 BrowserWindow 实例。基本上这行代码是根据渲染器进程(webContents)找到对应的窗口对象(BrowserWindow 实例)。*/const w = BrowserWindow.fromWebContents(webContents);w.setTitle(title);
}const createWindow = () => {const win = new BrowserWindow({width: 800,height: 800,webPreferences: {preload: path.join(__dirname, "preload.js"),},webContents: {openDevTools: true,},});win.loadFile("index.html");
};app.whenReady().then(() => {//ipcMain.on监听set-title行为,箭头从渲染器进程中使用setTitle方法发送而来的set-title消息(可以理解vue的事件监听emit)ipcMain.on("set-title", handleSetTitle);createWindow();
});

在这里插入图片描述
其中事件对象的结构如下
在这里插入图片描述

  1. 渲染器进程到主进程(双向):如下是一个事例,用户选中一个文件,显示该文件的路径。
index.html<button type="button" id="btn">Open a File</button>File path: <strong id="filePath"></strong><script src="./renderer.js"></script>
renderer.js
const btn = document.getElementById("btn");
const filePathElement = document.getElementById("filePath");btn.addEventListener("click", async () => {const filePath = await window.electronAPI.openFile();filePathElement.innerText = filePath;
});
preload.js
const { contextBridge, ipcRenderer } = require("electron/renderer");
contextBridge.exposeInMainWorld("electronAPI", {/* 异步发送一个需要响应的消息,并且等待主进程的回复。这是异步操作,但允许以类似于同步调用的方式(使用 async/await 或者基于 Promise 的方法)等待响应。*/openFile: () => ipcRenderer.invoke("dialog:openFile"),
});
const { app, BrowserWindow, ipcMain, dialog } = require("electron/main");
const path = require("node:path");async function handleFileOpen() {/* dialog 模块用于显示原生的对话框,例如文件打开、保存、消息提示等。dialog 模块是 Electron 提供的一个系统对话框接口,可以在主进程中使用,用于与用户进行交互。dialog 模块通过其 showOpenDialog 方法用于显示一个文件选择对话框。这个方法是异步的,它会返回一个 Promise。当用户选择文件并关闭对话框时,Promise 被解决(resolved),并带有一个对象,这个对象包含了两个属性:canceled 和 filePaths。canceled 是一个布尔值,表示用户是否取消了对话框而没有选择任何文件filePaths 是一个数组,包含用户选择的一个或多个文件的完整路径。*/const { canceled, filePaths } = await dialog.showOpenDialog();if (!canceled) {return filePaths[0];}
}function createWindow() {const mainWindow = new BrowserWindow({webPreferences: {preload: path.join(__dirname, "preload.js"),},});mainWindow.loadFile("index.html");
}app.whenReady().then(() => {//会把处理完成的消息返回给渲染进程ipcMain.handle("dialog:openFile", handleFileOpen);createWindow();
});
  1. 主进程到渲染器进程:将消息从主进程发送到渲染器进程时,需要指定是哪一个渲染器接收消息。 消息需要通过其 ·WebContents 实例·发送到渲染器进程。 此 WebContents 实例包含一个 ·send ·方法,其使用方式与· ipcRenderer.send ·相同。如下实例是一个原生操作系统菜单控制的数字计数器。
index.htmlCurrent value: <strong id="counter">0</strong><script src="./renderer.js"></script>
renderer.js
const counter = document.getElementById("counter");window.electronAPI.onUpdateCounter((value) => {const oldValue = Number(counter.innerText);const newValue = oldValue + value;counter.innerText = newValue.toString();window.electronAPI.counterValue(newValue);
});
preload.js
const { contextBridge, ipcRenderer } = require("electron/renderer");
contextBridge.exposeInMainWorld("electronAPI", {onUpdateCounter: (callback) =>ipcRenderer.on("update-counter", (_event, value) => callback(value)),counterValue: (value) => ipcRenderer.send("counter-value", value),
});
main.js
const { app, BrowserWindow, Menu, ipcMain } = require("electron/main");
const path = require("node:path");function createWindow() {const mainWindow = new BrowserWindow({webPreferences: {preload: path.join(__dirname, "preload.js"),},});const menu = Menu.buildFromTemplate([{label: app.name,submenu: [{click: () => mainWindow.webContents.send("update-counter", 1),label: "Increment",},{click: () => mainWindow.webContents.send("update-counter", -1),label: "Decrement",},],},]);Menu.setApplicationMenu(menu);mainWindow.loadFile("index.html");// Open the DevTools.mainWindow.webContents.openDevTools();
}app.whenReady().then(() => {ipcMain.on("counter-value", (_event, value) => {console.log(value); // 主进程中输出打印});createWindow();
});

在这里插入图片描述

  1. 渲染器进程到渲染器进程:没有直接的方法可以使用 ipcMain 和 ipcRenderer 模块在 Electron 中的渲染器进程之间发送消息。将主进程作为渲染器之间的消息代理。 这需要将消息从一个渲染器发送到主进程,然后主进程将消息转发到另一个渲染器。从主进程将一个 MessagePort 传递到两个渲染器。 这将允许在初始设置后渲染器之间直接进行通信。

进程沙盒化

从 Electron 20 开始,渲染进程默认启用了沙盒,无需进一步配置。

相关文章:

electron基础使用

安装以及运行 当前node版本18&#xff0c;按照官网提供操作&#xff0c;npm init进行初始化操作&#xff0c;将index.js修改为main.js&#xff0c;执行npm install --save-dev electron。&#xff08;这里我挂梯子下载成功了。&#xff09;&#xff0c;添加如下代码至package.…...

9.华为交换机telnet远程管理配置aaa认证

目的&#xff1a;telnet远程管理设备 LSW1配置 [Huawei]int Vlanif 1 [Huawei-Vlanif1]ip add 1.1.1.1 24 [Huawei-Vlanif1]q [Huawei]user-interface vty 0 4 [Huawei-ui-vty0-4]authentication-mode aaa [Huawei-ui-vty0-4]q [Huawei]aaa [Huawei-aaa]local-user admin pass…...

xcode报错合集,你都遇到过哪些跳不过的坑

1.报错Consecutive declarations on a line must be separated by ; 其实我这里是用因为创建了一个结构体&#xff0c;然后在没有使用State的情况下&#xff0c;修改它的属性了 当然加上State依然报错&#xff1a; 应该在UI事件中修改&#xff1a;...

六面体大米装袋机长期稳定运行原因分析

随着现代化农业生产的发展&#xff0c;六面体大米装袋机已成为粮食加工行业不可或缺的重要设备。然而&#xff0c;如何确保这些机器长期稳定运行&#xff0c;提高生产效率&#xff0c;降低维护成本&#xff0c;一直是广大粮食加工企业关注的焦点。星派将为您揭示六面体大米装袋…...

android的surface

相信很多Android开发者都知道Canvas类是UI的画布&#xff08;虽然这种说法并不严谨&#xff09;&#xff0c;因为我们在Canvas上完成各种图形的绘制&#xff0c;那么我们Activity上的各种交互控件又是如何展示并渲染到屏幕上的呢&#xff0c;所以在另一个层面上也有一个“画布”…...

Z世代职场价值观的重塑:从“班味”心态到个人成长的追求

近日&#xff0c;社交平台Soul APP联合上海市精神卫生中心&#xff08;俗称“宛平南路600号”&#xff09;发布《2024年Z世代职场心理健康报告》&#xff08;下称“报告”&#xff09;&#xff0c;发现今天的年轻人正以其独特的价值观和行为模式&#xff0c;重新定义成功与成就…...

【Python】Python 2 测试网络连通性脚本

文章目录 前言1. 命令行传参2. 代码 前言 最近在只有python2的服务器上部署服务&#xff0c;不能用三方类库&#xff0c;这里出于好奇心学习下python。这里简单做个脚本&#xff0c;实现了检验网络连通性的功能&#xff08;类似于curl&#xff09;。 1. 命令行传参 使用命令…...

瓦罗兰特教你怎么玩低价区+超适配低价区的免费加速器

《无畏契约》&#xff08;VALORANT&#xff09;是一款款英雄为核心的5V5第一人称战术射击PC游戏。在瓦罗兰特游戏中&#xff0c;玩家完成每日任务即可以获得大量的经验升级&#xff0c;另外我们也可以多多完成主线和支线任务&#xff0c;来加快升级的速度。玩家通过挑战副本&am…...

Linux安装kvm虚拟机

kvm是基于内核的虚拟机&#xff0c;为什么要用kvm不用vmware、virtual box… 只有一个原因&#xff0c;它非常快&#xff01;本机使用linux开发也是因为它快&#xff01;linux在老电脑上都能流畅运行&#xff0c;更别说现代电脑&#xff0c;如果你觉得装Linux并没有比win快多少…...

@pytest.fixture与@pytest.mark.parametrize结合实现参数化

背景&#xff1a;测试数据既要在fixture方法中使用&#xff0c;同时也在测试用例中使用 使用方法&#xff1a;在使用parametrize的时候添加"indirectTrue"参数。pytest可以实现将参数传到fixture方法中&#xff0c;也可以在当前测试用例中使用。 原理&#xff1a;参…...

uniapp中unicloud接入支付宝订阅消息完整教程

经过无数次的尝试,终于还是让我做出来了 准备工作 设置接口加签方式 使用支付宝小程序订阅消息,首先要设置接口加签方式,需要下载支付宝开放平台密钥工具,按照步骤生成秘钥,然后按照支付宝设置密钥加签方式添加接口加签方式。 有一点需要注意的,因为要在云函数中使用,…...

PHP 标准建议psr

PSR-1: Basic Coding Standard&#xff08;基础编码标准&#xff09; PSR-1 定义了PHP代码文件的基本编写规范&#xff0c;它关注的是代码文件的结构和一些通用的编程约定&#xff0c;主要包括&#xff1a; 文件命名&#xff1a;PHP文件必须以.php为后缀。PHP标签&#xff1a…...

第九届信也科技杯全球AI算法大赛——语音深度鉴伪识别参赛A榜 0.968961分

遗憾没有进复赛&#xff0c;只是第41名。先贴个A榜的成绩。A榜的前三十名晋级&#xff0c;个个都是99分的大佬&#xff0c;但是B榜的成绩就有点低了&#xff0c;应该是数据不同源的问题&#xff0c;第一名0.78分。官网链接&#xff1a;语音深度鉴伪识别 官方baselin:https://g…...

【设计模式(三) 设计模式的分类 】

设计模式&#xff08;DesignPattern&#xff09;是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。 使用设计模式的目的 &#xff1a;为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编写真正工程化&#xff1b;设计模式是软件工程…...

Linux进程概念(个人笔记)

Linux进程概念 1.冯诺依曼体系结构2.操作系统&#xff08;先描述&#xff0c;再组织&#xff09;3.进程3.1查看进程的方式3.2通过系统调用获取进程标识符3.4查看进程中常见字段状态的指令3.3fork创建子进程3.3.1fork的原理 3.4进程状态3.5进程优先级3.5.1Linux内核的调度队列与…...

每天五分钟计算机视觉:如何在现有经典的卷积神经网络上进行微调

本文重点 在深度学习领域,卷积神经网络(Convolutional Neural Networks,CNN)因其强大的特征提取和分类能力而广泛应用于图像识别、自然语言处理等多个领域。然而,从头开始训练一个CNN模型往往需要大量的数据和计算资源,且训练时间较长。幸运的是,迁移学习(Transfer Le…...

10个典型的MySQL笔试题和面试题

提供10个典型的MySQL笔试题和面试题作为示例&#xff0c;并给出答案或解释。如果需要更多题目&#xff0c;可以根据这些示例进行扩展或参考相关文档。 1. MySQL是什么&#xff1f; 答案&#xff1a;MySQL是一个关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c…...

AI大模型的TTS评测

L-MTL&#xff08;Large Multi-Task Learning&#xff09;Models 是一种大规模多任务学习模型&#xff0c;通过结合 Mixture of Experts&#xff08;MMoE&#xff09;框架与 Transformer 模型&#xff0c;实现对 TTS&#xff08;Text-to-Speech&#xff09;系统中多个评估指标的…...

推荐一款可以下载B站视频和音频的工具

cobalt是一个免费的下载网站&#xff0c;主要是用于载视频和音频。只要你把相应的网址复制下来&#xff0c;然后打开cobalt网站&#xff0c;黏贴网址&#xff0c;选择要下载的格式&#xff0c;就可以下载相应的音频或者视频了。 该网站非常简洁&#xff0c;使用也很简单。目前只…...

中科数安 |-透明加密软件_无感透明加密 - 源头有保障

中科数安的透明加密软件是一款专为保护企业数据安全而设计的高级产品&#xff0c;它采用了无感透明加密技术&#xff0c;确保源头数据的安全可靠。 ——www.weaem.com 以下是该软件的主要特点和功能概述&#xff1a; 无感透明加密&#xff1a; 中科数安的透明加密软件能够在用…...

ui自动化selenium,清新脱俗代码,框架升级讲解

一&#xff1a;简化 1. 新建common 包 新建diver.py 封装浏览器驱动类 from selenium import webdriverclass Driver():"""浏览器驱动类定义 一个【获取浏览器驱动对象driver的方法】。支持多种类型浏览器"""def get_driver(self,browser_typ…...

【吊打面试官系列-Mysql面试题】Myql 中的事务回滚机制概述 ?

大家好&#xff0c;我是锋哥。今天分享关于 【Myql 中的事务回滚机制概述 ?】面试题&#xff0c;希望对大家有帮助&#xff1b; Myql 中的事务回滚机制概述 ? 事务是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做要么全不做&#xff0c;是一个不可分割的工作单位…...

VMware虚拟机三种网络模式设置 - Bridged(桥接模式)

一、前言 由于linux目前很热门&#xff0c;越来越多的人在学习linux&#xff0c;但是买一台服务放家里来学习&#xff0c;实在是很浪费。那么如何解决这个问题&#xff1f;虚拟机软件是很好的选择&#xff0c;常用的虚拟机软件有vmware workstations和virtual box等。 在使用虚…...

关于Panabit在资产平台中类型划分问题

现场同事问了一个问题&#xff1a;Panabit能不能当做CentOS接入&#xff1f; 我第一反应是&#xff1a;Panabit是个什么鬼&#xff1f;为啥要混编接入&#xff1f;后期维护都是事啊。所以&#xff0c;我就想回答&#xff1a;不能&#xff01; 但是&#xff0c;最好要给出一个…...

【C语言】12.C语言内存函数

文章目录 1.memcpy使用和模拟实现2.memmove使用和模拟实现3.memset函数的使用4.memcmp函数的使用 memcpy&#xff1a;内存拷贝 memmove&#xff1a;内存移动 memset&#xff1a;内存设置 memcmp&#xff1a;内存比较 1.memcpy使用和模拟实现 memcpy&#xff1a;内存拷贝 void…...

Django:如何将多个数据表内容合在一起返回响应

一.概要 Django写后端返回响应时&#xff0c;通常需要返回的可能不是一个数据表的内容&#xff0c;还包括了这个数据表的外键所关联的其他表的一些字段&#xff0c;那该如何做才能把他们放在一起返回响应呢&#xff1f; 二.处理方法 在这里我有三个数据表 第一个是航空订单&…...

棱镜七彩荣获CNNVD两项大奖,专业能力与贡献再获认可!

6月18日&#xff0c;国家信息安全漏洞库&#xff08;CNNVD&#xff09;2023年度工作总结暨优秀表彰大会在中国信息安全测评中心成功举办。棱镜七彩凭借在漏洞方面的突出贡献和出色表现&#xff0c;被授予“2023年度优秀技术支撑单位”与“2023年度最佳新秀奖”。 优秀技术支撑单…...

uni-app中使用富文本rich-text个人经验

rich-text是在uni-app一个内置组件&#xff0c;用于高性能地渲染富文本内容。先贴一下官方的属性列表&#xff1a; 先说一下“selectable” 长按选择区域复制&#xff0c;这个我在APP项目中 不起作用&#xff0c;可能像文档说的&#xff0c;只支持“百度小程序”吧。在APP端起作…...

Matlab|基于V图的配电网电动汽车充电站选址定容-可视化

1主要内容 基于粒子群算法的电动汽车充电站和光伏最优选址和定容 关键词&#xff1a;选址定容 电动汽车 充电站位置 仿真平台&#xff1a;MATLAB 主要内容&#xff1a;代码主要做的是一个电动汽车充电站和分布式光伏的选址定容问题&#xff0c;提出了能够计及地理因素和服…...

从零开始! Jupyter Notebook的安装教程

&#x1f680; 从零开始! Jupyter Notebook的安装教程 摘要 &#x1f4c4; Jupyter Notebook 是一个广受欢迎的开源工具&#xff0c;特别适合数据科学和机器学习的开发者使用。本文将详细介绍从零开始安装 Jupyter Notebook 的步骤&#xff0c;包括各种操作系统的安装方法&am…...

龙岗做网站/临安网站seo

NET中级开发工程师岗位职责1、熟练掌握 WebApi, ASP.NET MVC, Entity Framework,.NET CORE等技术&#xff0c;精通JQuery、Vue、Bootstrap等前端开发框架&#xff1b;2、熟悉Redis、Oracle,MySQL,RabbitMQ&#xff0c;MongoDB&#xff0c;ES等数据库&#xff1b;3、掌握多线程、…...

建设厅里网站查不到外地施工单位/百度热点榜单

双系统教程很多&#xff0c;此处搬运官方教程的Link&#xff0c;非常全面和详细&#xff0c;既作为自己笔记使用&#xff0c;也供读者借鉴&#xff1b; dell计算机双系统安装教程&#xff1a; Ubuntu 以及 Windows 8 至 Windows 11 中的某个操作系统 虽然这是基于dell笔记本的教…...

mac 装 wordpress/百度竞价sem入门教程

下午在配置Zend_Tool时&#xff0c;出现了标题那样的错误&#xff0c;在个google上搜索了一下&#xff0c;看到一篇文章的方法&#xff0c;解决了。要将php.exe所在的目录php添加到环境变量当中即可。我使用的php环境是wamp集成 的&#xff0c;这可能是造成以上错误的原因。php…...

注册卡wordpress/营销型高端网站建设

《C语言学生通信录管理系统课程设计报告》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《C语言学生通信录管理系统课程设计报告(18页珍藏版)》请在人人文库网上搜索。1、实验名称 &#xff1a;学生通信录管理系统 实验项目性质&#xff1a;综合性、设计性所涉及课程&…...

网站建设尺寸像素是多少/网络营销的主要工作有哪些

MySQL中添加唯一约束和联合唯一约束 转载于:https://www.cnblogs.com/jingzhishen/p/5104685.html...

网站被攻击打不开怎么办/百度风云排行榜

据英国每日邮报报道&#xff0c;时空织布里的涟漪或可以揭示宇宙在140亿年前是如何产生的&#xff0c;然而寻找这些名为“引力波”的涟漪却一直难以捉摸。现在美国科学家们声称他们发现了改善用于检测宇宙大爆炸的引力波的探测器的方法。 ​宇宙大爆炸残留的引力波 美国加州理…...