WPF 应用迁移到 Electron 框架过程记录
前一段时间我用 WPF 开发了一个查看 emoji 表情的小工具 https://github.com/he55/EmojiViewer ,由于最近我使用 macOS 系统比较多,我想能在 macOS 系统上也能使用这个工具。于是我尝试将 WPF 应用迁移到 Electron 框架,感觉这个框架很强大,在这里记录一下应用迁移的过程。

安装 Electron 环境
- 安装 nodejs。到官网 https://nodejs.org/en 下载最新的 nodejs,然后安装

- 打开命令行输入
git clone https://github.com/electron/electron-quick-start.git命令克隆 Electron 模板项目,使用模板可以快速搭建应用。 - 然后使用
cd electron-quick-start目录进入到目录,接着运行npm install命令还原项目。 - 使用 vscode 打开文件夹,项目文件如下

编写代码
- Electron 分为主进程和渲染进程,对文件、系统和窗口的操作需要在主线程,界面渲染在渲染进程。创建窗口属于主进程的工作,需要到
main.js文件编写代码。创建窗口使用BrowserWindow对象,width和height分别设置窗口宽度和高度,autoHideMenuBar设置是否隐藏菜单,最后使用loadFile加载页面文件并显示窗口。
function createWindow() {
const mainWindow = new BrowserWindow({
width: 915,
height: 560,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
- 监听
whenReady事件,等待应用初始化完成后显示窗口
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
- 修改
index.html文件,界面部分使用了 vue 进行渲染
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="vue.global.js"></script>
<link href="./styles.css" rel="stylesheet">
<title>EmojiViewer</title>
</head>
<body>
<div id="app" class="container">
<ul class="left">
<li v-for="(item, key) in categories" :class="{active: item.isActive}" @click="catetoryItemClick(item)">{{ key }}</li>
</ul>
<ul class="main" ref="mainElement">
<li v-for="emoji in emojis" :class="{active: emoji.isActive}" @click="emojiItemClick(emoji)">
<img :src="emoji.previewImage" alt="">
<p>{{emoji.name}}</p>
</li>
</ul>
<div class="right">
<img :src="selectedEmoji.previewImage">
<p>{{ selectedEmoji.name }}</p>
<button @click="copyEmoji(selectedEmoji)" type="button">Copy Emoji</button>
<button @click="copyImage(selectedEmoji)" type="button">Copy Image</button>
<button @click="openFile(selectedEmoji)" type="button">Open File</button>
</div>
</div>
<script src="./renderer.js"></script>
</body>
</html>
- 在
renderer.js文件中编写页面处理代码
window.addEventListener('DOMContentLoaded', async () => {
const { createApp, ref, onMounted } = Vue
let emojiData = await ipc.getData()
createApp({
setup() {
const mainElement = ref(null)
const categories = ref(emojiData)
const emojis = ref([])
const selectedEmoji = ref({})
function copyEmoji(emoji) {
ipc.ipc('writeText', emoji.metadata.glyph)
}
function copyImage(emoji) {
ipc.ipc('writeImage', emoji.previewImage)
}
function openFile(emoji) {
ipc.ipc('showItemInFolder', emoji.previewImage)
}
let lastSelectedEmojis
function catetoryItemClick(items) {
if (lastSelectedEmojis) {
lastSelectedEmojis.isActive = false
}
items.isActive = true
lastSelectedEmojis = items
// const main = document.querySelector('.main')
mainElement.value.scrollTop = 0
emojis.value = items
}
function emojiItemClick(emoji) {
if (selectedEmoji.value) {
selectedEmoji.value.isActive = false
}
emoji.isActive = true
selectedEmoji.value = emoji
}
onMounted(() => {
catetoryItemClick(emojiData['Activities'])
emojiItemClick(emojiData['Activities'][0])
})
return {
mainElement,
categories,
emojis,
selectedEmoji,
catetoryItemClick,
emojiItemClick,
copyEmoji,
copyImage,
openFile,
}
}
}).mount('#app')
})
- 读取文件,node 提供了文件操作相关的 api 可以很方便的操作文件系统。
function loadData(assetPath) {
const dirs = fs.readdirSync(assetPath)
const data = []
const groupData = {}
for (const dir of dirs) {
const fullPath = path.resolve(assetPath, dir)
const metadata = require(path.resolve(fullPath, 'metadata.json'))
let previewImage
let imagePaths = [path.resolve(fullPath, '3D'), path.resolve(fullPath, 'Default', '3D')]
for (const imagePath of imagePaths) {
if (fs.existsSync(imagePath)) {
let files = fs.readdirSync(imagePath)
if (files.length === 0)
return
previewImage = path.resolve(imagePath, files[0])
}
}
const { unicode, group } = metadata
const obj = {
metadata,
id: unicode,
name: dir,
previewImage,
}
data.push(obj)
if (!groupData[group])
groupData[group] = []
groupData[group].push(obj)
}
return groupData
}
完整代码(WPF 版本) https://github.com/he55/EmojiViewer
完整代码(vue 版本) https://github.com/he55/web-learn/tree/main/9.electron-emoji-viewer(vue)
完整代码(js 原生版本) https://github.com/he55/web-learn/tree/main/6.electron-emoji-viewer
WPF 应用迁移到 Electron 框架过程记录的更多相关文章
- 将ibatis迁移到mybatis3的过程记录
将ibatis迁移到mybatis3的过程记录 场景:有些以前的老项目是使用ibatis开发的,现在有转换成mybatis3的需求. 环境准备:需要安装Ant,以下是本人的安装版本,具体怎么安装不再赘 ...
- 半个前端新手入门Electron的过程
前言 先说几句废话,本人是一名 web 后端开发,主语言是 java,在学 Electron 之前,只会一点点 HTML和 JavaScript.本文讲的也是我学习 Electron 的过程,而非教程 ...
- 将基于 .NET Framework 的 WPF 项目迁移到基于 .NET Core 3
在 Connect(); 2018 大会上,微软发布了 .NET Core 3 Preview,以及基于 .NET Core 3 的 WPF:同时还发布了 Visual Studio 2019 预览版 ...
- 金蝶Apusic中间件适配JetSpeed2过程记录
金蝶Apusic中间件适配JetSpeed2过程记录: 1.安装金蝶并配置域,确保域运行正常. 2.参考<JetSpeed2部署至Apusic操作步骤记录>进行应用迁移. https:// ...
- Electron安装过程深入解析(读完此文解决Electron应用无法启动,无法打包的问题)
1. 安装Electron依赖包 开发者往往通过npm install(或 yarn add)指令完成为Node.js工程安装依赖包的工作, 安装Electron也不例外,下面是npm和yarn的安装 ...
- 升级Windows 10 正式版过程记录与经验
升级Windows 10 正式版过程记录与经验 [多图预警]共50张,约4.6MB 系统概要: 预装Windows 8.1中文版 64位 C盘Users 文件夹已经挪动到D盘,并在原处建立了符号链接. ...
- 双系统Ubuntu分区扩容过程记录
本人电脑上安装了Win10 + Ubuntu 12.04双系统.前段时间因为在Ubuntu上做项目要安装一个比较大的软件,导致Ubuntu根分区的空间不够了.于是,从硬盘又分出来一部分空间,分给Ubu ...
- .NET 4.5+项目迁移.NET Core的问题记录
.NET 4.5+项目迁移.NET Core的问题记录 这几天试着把目前的开发框架迁移到新的.net core平台,中间遇到的问题在这里简单记录一下. 迁移过程遇到的最大的问题IOC容器.我目前使用的 ...
- SVN迁移到Git的过程(+ 一些技巧)
SVN迁移到Git的过程(+ 一些技巧) 李顺利 Key Words SVN,Git,Clone,Conversion,Tips,VCS,Pro Git 关于在VCS中SVN和Git之间的迁移(Clo ...
- CentOS 5.5 下安装Countly Web Server过程记录
CentOS 5.5 下安装Countly Web Server过程记录 1. 系统更新与中文语言包安装 2. 基本环境配置: 2.1. NodeJS安装 依赖项安装 yum -y install g ...
随机推荐
- lua开发和调试环境
Lua开发环境搭建 Lua官网提供源码下载需要自己编译,Lua官网:https://www.lua.org/ftp/ lua for windows.exe(占二十多MB那个) 目前在网络上没有找到 ...
- gRPC学习小札
gRPC 前言 为什么使用gRPC 传输协议 传输效率 性能消耗 gRPC入门 gRPC流 证书认证 使用根证书 gRPC实现token认证 和Web服务共存 验证器 REST接口 grpcurl工具 ...
- Flask 实现文件上传下载
Flask 针对文件的上传下载相关代码片段,多种方法,包括限制文件格式,大小等. 实现图片文件上传 # name: 简单的实现文件上传任务. import os from flask import F ...
- 从嘉手札<2024-1-29>
补一下以前的几篇日记 2018-4-6 当一个人不在纠结没有什么 而是开始珍视他所拥有的一切的时候 才算得上真正的成熟 个人的意志 不能因受到社会的压力而软弱 也不能受到自然的压力而萎缩 而应当如冬日 ...
- Java多线程-ThreadLocal(六)
为了提高CPU的利用率,工程师们创造了多线程.但是线程们说:要有光!(为了减少线程创建(T1启动)和销毁(T3切换)的时间),于是工程师们又接着创造了线程池ThreadPool.就这样就可以了吗?-- ...
- ThinkPHP 6.0 SQL注入漏洞修复
公司买的官网被政府网安检测出SQL注入漏洞: 隐患描述 SQL漏洞证明语句: python3 sqlmap.py -u "http://xxxx?keywords=1" -p ke ...
- HBase Shell将命令执行结果导出到文件
1.将Hbase shell执行结果输出到文件 echo "scan 'test'" | hbase shell>my.txt 2.查看表的region数 list_regi ...
- [JVM]逃逸分析
逃逸分析 JVM的内存分配策略 首先回顾一下JVM的内存分配策略. JVM的内存包括方法区.堆.虚拟机栈.本地方法栈.程序计数器.一般情况下JVM运行时的数据都是存在栈和堆上的.栈用来存放一些基本变量 ...
- NC207781 迁徙过程中的河流
题目链接 题目 题目描述 牛市的幸存的先民在流星雨之后就忍痛离开了这片土地,选择迁徙,在迁徙的途中,他们需要渡过一条河.因为牛市的树木在流星雨中被严重破坏,所以他们只造出了一艘小船,船太小了,一次只能 ...
- OpenWrt 21.02.2 记录: PPPoE, Wireguard
OpenWrt 21.02 OpenWrt 21.02.2 是 OpenWrt 当前最新的稳定版, 内核 5.4.179, 这个内核已经内置了 Wireguard 模块 root@OpenWrt:~# ...