如何把Electron做成一个Runtime,让多个应用共享同一个Electron

摘要:
最终安装人员的职责。当最终安装程序在最终用户的计算机上运行时,它将完成以下任务:检查最终用户的注册表,看看它是否安装了我们的ElectronRuntime。如果没有,请下载Electron的发行版,将其发布到特定目录,并将其记录在注册表中。

这个问题涉及到很多知识,而且要想把这个Runtime做好很绕。

下面我就说一下我的思路:
(以下内容以Windows平台为基础,Mac平台和Linux平台还得去调查一下,才能确定是否可行)

首先,我们先区分三类用户:

  1. Runtime建设者(就是我们)
  2. Runtime使用者(就是使用Runtime的开发者)
  3. 最终用户(就是使用Runtime开发者开发的应用的那些用户)

接下来我们就以Runtime建设者的视角来审视这项工作

首先我们要为Runtime使用者提供一个专有的打包工具,我们就叫它:打包工具。这个打包工具还内置了几个可执行程序,我们给他们起个名字,分别叫:

  • 最终安装程序
  • 最终执行程序
  • 最终卸载程序

好,我们一个一个聊他们的职责

打包工具的职责
按Runtime使用者的要求修改最终执行程序的图标、应用签名、版本、版权、文件名等资源信息;
按Runtime使用者的要求修改最终卸载程序的图标、应用签名、版本、版权、文件名等资源信息;
把最终执行程序、最终卸载程序与Runtime使用者开发好的HTML/CSS/JS等静态文件放到一起,压缩成一个压缩包,我们叫他:资源文件
把这个资源文件以资源的形式封装到最终安装程序中;
按Runtime使用者的要求修改这个最终安装程序的图标、应用签名、版本、版权、文件名等资源信息;
(修改资源的代码,后文有介绍)

这几个工作完成之后,Runtime使用者就可以把这个最终安装程序分发给最终用户了。

最终安装程序的职责
这个最终安装程序在最终用户的电脑上运行时,会完成以下工作:

检查最终用户的注册表,看其是否安装了我们的Electron Runtime
如果没有安装,则下载Electron的发行版,释放到一个特定目录下,并在注册表记下来。
在这个特定目录下记录当前应用的信息(卸载当前应用时要用到);
把自身的资源释放到最终用户指定的目录内,也就是前文说的资源文件
解压缩资源文件得到最终执行程序、最终卸载程序和Runtime使用者开发的HTML/CSS/JS等静态文件
写注册表记录最终卸载程序的位置,这样用户就可以在控制面板里卸载我们的程序了。
按最终用户的要求,创建开始菜单图标、桌面图标,这些图标均指向最终执行程序
(读取资源的代码,后文有介绍)

如果最终用户工作在没有网络的环境下,那么我们也可以允许Runtime使用者把Electron Runtime打包到最终安装程序内,这是打包工具的职责。

如果担心Electron官方提供的下载地址速度慢,可以考虑使用国内镜像地址:​npmmirror.com/mirrors/electron/

最终执行程序的职责
检查用户注册表,找到Electron Runtime的放置路径
启动Electron Runtime并把当前应用的入口程序当做参数传给Electron.exe,应用入口程序就是Runtime使用者开发HTML/CSS/JS等静态文件之一,
electron.exe path/to/entry.js
最终卸载程序的职责
删除安装目录下的文件
删除注册表的卸载程序信息
删除Electron Runtime所在目录下的应用程序信息,如果发现没有别的应用在依赖Electron Runtime了,那么就把Electron Runtime所在目录也删掉。


把一个文件作为资源写入一个可执行程序的代码如下所示:

HANDLE hFile;
DWORD dwFileSize,dwBytesRead;
LPBYTE lpBuffer;
char szFile[MAX_PATH+1] = {0};
::GetDlgItemText(hwnd,EditId,szFile,MAX_PATH);
hFile = CreateFile(szFile,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
dwFileSize = GetFileSize(hFile, NULL);
lpBuffer = new BYTE[dwFileSize];
ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL);
HANDLE hResource = BeginUpdateResource(szFilePath, FALSE);
UpdateResource(hResource,RT_RCDATA,MAKEINTRESOURCE(EditId),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPVOID)lpBuffer,dwFileSize);
EndUpdateResource(hResource, FALSE);
delete [] lpBuffer;
CloseHandle(hFile);
return 1;

可执行程序读取自身资源,把资源写到指定路径下的代码如下:

HMODULE hInstance = ::GetModuleHandle(NULL);
TCHAR szFilePath[MAX_PATH + 1];
GetPath(szFilePath,resourceName,hInstance);
HRSRC hResID = ::FindResource(hInstance,resourceID,RT_RCDATA);
HGLOBAL hRes = ::LoadResource(hInstance,hResID);
LPVOID pRes = ::LockResource(hRes);
DWORD dwResSize = ::SizeofResource(hInstance,hResID);
if(!dwResSize) return 0;
HANDLE hResFile = CreateFile(szFilePath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD dwWritten = 0;
WriteFile(hResFile,pRes,dwResSize,&dwWritten,NULL);
CloseHandle(hResFile);
if(dwResSize == dwWritten) return 1;
return 0;

这两段代码是从我的一个项目中摘抄出来的,仅供参考。

遗留的问题
我们并没有考虑多Electron版本共存的问题;
此方案高度依赖Windows API,跨平台实现差异肯定会比较大;
应用程序启动后,任务栏的图标是Electron Runtime的图标,而非Runtime使用者指定的图标(这是有解决办法的);

如何把Electron做成一个Runtime,让多个应用共享同一个Electron第1张

 

免责声明:文章转载自《如何把Electron做成一个Runtime,让多个应用共享同一个Electron》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MFC控件Slider Control的使用有关CKEditor和CKFinder的集成下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

《ArcGIS Runtime SDK for Android开发笔记》——(15)、要素绘制Drawtools3.0工具DEMO

1、前言 移动GIS项目开发中点线面的要素绘制及编辑是最常用的操作,在ArcGIS Runtime SDK for iOS 自带AGSSketchLayer类可以帮助用户快速实现要素的绘制,图形编辑。但是在ArcGIS Runtime SDK for Android的版本中并没有提供类似的功能,实现过程相对较复杂。(10.2.8及以下版本需要用户自定义扩展...

Go日志库使用-logrus

golang日志库 golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数对于更精细的日志级别、日志文件分割以及日志分发等方面并没有提供支持。 所以催生了很多第三方的日志库,但是在golang的世界里,没有一个日志库像slf4j那样在Java中具有绝对统治地位。golang中,流行的日志框架包括logrus、zap、ze...

gvisor debug

Stack traces Debugger ProfilingDocker Proxy To enable debug and system call logging, add the runtimeArgs below to your Docker configuration (/etc/docker/daemon.json): { "r...

Debug 和 Release 编译方式的本质区别

一、Debug 和 Release 编译方式的本质区别       Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。       Debug 和 Release 的真正秘密,在于一组编译选项。下面列出了分别...

Node JS与Electron安装配置

安装NodeJS 1.下载NodeJS 2.安装NodeJS 安装过程如下,忽略的过程中直接点击下一步即可。 3.配置NodeJS 1.验证NodeJS安装 打开cmd直接输入 node -v npm -v 2.配置路径 这里视具体情况而定,我将会把NodeJS安装的第三方模块以及缓存位置更改在NodeJS根目录。打开cmd,输入 npm...

electron制作上位机软件篇(一):编译安装serialport

参考:https://blog.csdn.net/qq_25430563/article/details/87968837https://blog.csdn.net/weixin_36250061/article/details/103472978https://github.com/serialport/node-serialport/issues/17...