本文主要描述Electron中路径相关的问题
1、静态资源丢失的原因
Electron常见问题(二)Electron图标打包我们讨论过静态资源的打包elementui图标路径elementui图标路径,但是有时会遇到程序在本地环境运行时可以看到静态资源,产品发布后静态资源丢失的情况建造的。
这是带有托盘图标的示例。
通过extraResources复制操作将托盘图标的静态资源放入打包文件中
package.json
{
...
"build": {
...
"extraResources": [
{
"from": "icons/",
"to": "icons/"
} // 可以移动多个文件夹,from-to
],
...
},
...
}
打包好的图标会被复制到资源文件中
在本地环境中,我们使用相对路径导入图标来导入图标
const iconName =process.platform === 'win32' ?
'icons/windows-icon.png' : 'icons/iconTemplate.png';
const ningImage = nativeImage.createFromPath(iconName);
tray = new Tray(ningImage);
我们的主要代码将被打包在app.asar中
主代码打包位置
对于主代码来说,“icons/windows-icon.png”中图标的位置没有任何问题。
但在本地环境中,我们的主要代码在app/main.developments.ts中,所以'icons/windows-icon.png'找不到对应的图标。
本地项目
2、静态资源路径一致性处理方案-resolvePath
为了解决路径不一致的问题,我们可以封装一个resolvePath类,使本地环境的路径与产品环境的路径保持一致。
export default class PathUtils {
// 将startPath作为标准路径,静态资源的路径和项目中使用到的路径全部由startPath起始
public static startPath = path.join(__dirname, '..');
public static resolvePath = (dirPath) => {
return path.join(PathUtils.startPath, dirPath || '.');
};
}
这样对应的托盘图标导入形式就变成了
const iconName =
process.platform === 'win32'
? PathUtils.resolvePath('icons/windows-icon.png')
: PathUtils.resolvePath('icons/iconTemplate.png');
const ningImage = nativeImage.createFromPath(iconName);
tray = new Tray(ningImage);
3.常用路径---userPath/appData/documents
我们系统的配置文件一般是放在用户目录下的,比如C://User/Administrator/xxxconfig.json,这个路径通常称为userProfile,这是初始情况,有的用户系统盘放在D盘驱动器E盘和其他盘一样,对应的用户目录的位置也会发生变化。
所以我们的用户目录通常是使用userProfile来获取的,也可以在Electron的环境变量中找到。
process.env['USERPROFILE'];
同一个用户的缓存目录APPDATA路径为
process.env['APPDATA']
另一个常见的路径是文档。 知名的QQ、陌陌收到的文件通常都会缓存在这个位置。
公共路径文档库
Electron中找不到文档的位置,也可以自动编辑文档映射的路径。
但它最终会出现在注册表中。 所以我们需要做一些事情来读取注册表。
幸运的是,网上可以找到regedit组件,可以让nodejs访问注册表。
那么我们只需要找到该文档对应的位置即可。
注册表中的文档位置
4.pathUtil的封装
userPath/appData/document路径减少了,我们的pathUtil也应该升级,如下
export default class PathUtils {
public static startPath = path.join(__dirname, '..');
public static userPath = process.env['USERPROFILE'];
public static userDocPath;
public static appdataPath = process.env['APPDATA'];
public static resolvePath = (dirPath) => {
return path.join(PathUtils.startPath, dirPath || '.');
};
public static resolveUserPath = (dirPath) => {
return path.join(PathUtils.userPath, dirPath || '.');
};
public static resolveUserDocPath = (dirPath) => {
return new Promise((resolve, reject) => {
getUserDoc().then((docPath: string) => {
PathUtils.userDocPath = docPath;
resolve(PathUtils.userDocPath);
});
});
};
}
const getUserDoc = () => {
return new Promise((resolve, reject) => {
const regedit = require('regedit');
regedit.setExternalVBSLocation(PathUtils.resolvePath('vbs'));
const key = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders';
regedit.list(key, function(err, result) {
if (err) {
console.error('Window Reg:', err);
} else {
try {
resolve(result[key].values['Personal'].value);
} catch (e) {
const docPath = path.join(PathUtils.userPath, 'Documents');
if (!fs.existsSync(docPath)) {
fs.mkdirSync(docPath);
}
resolve(docPath);
}
}
});
});
};