Electron erhält AppData beim Vorladen
P粉351138462
P粉351138462 2024-04-06 11:05:31
0
1
568

Wie erhalte ich das vorinstallierte AppData-Verzeichnis?

background.js

[...]

async function createWindow() {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__static, "preload.js"),
            nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
            contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
        },
    })
}

[...]

preload.js

const { contextBridge } = require('electron')

contextBridge.exposeInMainWorld(
    'configManager', 
    require("../src/utils/config-manager")
)

config-manager.js

const app = require("electron").app
const fs = require("fs")
const resourcePath = app.getPath('appData').replaceAll("\", "/") + "my-custom-path" // <---
const configPath = resourcePath + "config.json"
const defaultConfig = [ ... ]
let config;

function createFilesIfNotExists(){
    if (!fs.existsSync(resourcePath))
        fs.mkdirSync(resourcePath)
    
    if (!fs.existsSync(configPath)){
        fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 4))
        return true
    }

    return false
}

module.exports = {
    loadConfig() {
        createFilesIfNotExists()

        [...]

        return config
    }
}

Wenn ich das ausführe, erhalte ich diese Fehlermeldung.

TypeError: Cannot read property 'getPath' of undefined
    at Object.<anonymous> (VM77 config-manager.js:3)
    at Object.<anonymous> (VM77 config-manager.js:65)
    at Module._compile (VM43 loader.js:1078)
    at Object.Module._extensions..js (VM43 loader.js:1108)
    at Module.load (VM43 loader.js:935)
    at Module._load (VM43 loader.js:776)
    at Function.f._load (VM70 asar_bundle.js:5)
    at Function.o._load (VM75 renderer_init.js:33)
    at Module.require (VM43 loader.js:959)
    at require (VM50 helpers.js:88)
(anonymous) @ VM75 renderer_init.js:93

Ich denke, das passiert, weil „App“ später initialisiert wird.

Mein ultimatives Ziel ist es, die JSON-Konfiguration aus dem AppData-Verzeichnis zu lesen. Wenn es eine bessere Möglichkeit gibt, dies zu tun, lassen Sie es mich bitte wissen. Der Benutzer muss nicht in der Lage sein, die Konfiguration zur Laufzeit zu ändern. Aber ich muss in der Lage sein, den Standardwert in defaultConfig in die Konfigurationsdatei zu schreiben.

P粉351138462
P粉351138462

Antworte allen(1)
P粉569205478

app.getPath() 方法仅在应用程序“就绪”后才可用。使用 app.on('ready' () => { ... }); 检测 'ready' 事件。有关更多信息,请参阅 Electron 的事件:'ready' 事件。

关于您的 preload.js 脚本,直接在其中包含函数有时会使内容难以阅读和理解(即使它仅由 require 实现)。目前,该文件没有关注点分离。 IE:您的“配置”功能混合在 preload 脚本中。如果您希望分离问题,那么您应该从 preload.js 文件中重构您的“配置”代码,并将其放在自己的文件中。这样,您的 preload.js 文件仅用于配置 IPC 通道和传输关联数据(如果有)。


好吧,让我们看看如何解决 app.getPath('appData') 问题。

在您的 main.js 文件中,检测您的应用程序何时“就绪”,然后通过您的 config-manager.js 文件获取 appData 目录。

main.js(主线程)

const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;

let appConfig = require('config-manager');
let appMainWindow = require('mainWindow');

let mainWindow;

app.whenReady().then(() => {
    // Load the config.
    let configStatus = appConfig.loadConfig();
    console.log(configStatus);

    let config = appConfig.getConfig();
    console.log(config);

    // Create your main window.
    mainWindow = appMainWindow.create()

    ...

    })
})

在您的 config-manager.js 文件中,我已将您的“路径”变量移至 loadConfig() 函数范围,因为它们仅由该函数使用。如果您需要将它们公开以供文件中其他位置使用,则需要将它们移回 loadConfig() 函数作用域之外。

我将对 ElectronApp.getPath('appData') 的引用移至 loadConfig() 函数中,因为在应用程序“就绪”后从 main.js 调用此函数。

我添加了辅助函数 pathExists() 因为它的实现被多次使用。

最后,我添加了 getConfig() 函数,以便在需要时从应用程序主线程中的任何位置轻松获取配置对象(只要将其包含在需要使用它的文件中即可)。IE: let appConfig = require('config-manager')

config-manager.js(主线程)

const electronApp = require("electron").app

const nodeFs = require("fs")

const defaultConfig = [ ... ];

let config;

function loadConfig() {
    let resourcePath = app.getPath('appData').replaceAll("\\", "/") + "my-custom-path";
    let configPath = resourcePath + "config.json";

    if (! pathexists(resourcePath)) {
        nodeFs.mkdirSync(resourcePath);
    }

    if (! pathexists(configPath)) {
        nodeFs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 4));
        config = defaultConfig;
    } else {
        config = JSON.parse(nodeFs.readFileSync(configPath , 'utf8'));
    };
}

function getConfig() {
    return config;
}

function pathExists(path) {
    return (fs.existsSync(path)) ? true : false;
}

module.exports = {loadConfig, getConfig}

典型的 preload.js 脚本看起来像这样。

const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// White-listed channels.
const ipc = {
    'render': {
        // From render to main.
        'send': [
            'config:updateConfig' // Example only
        ],
        // From main to render.
        'receive': [
            'config:showConfig' // Exmaple only
        ],
        // From render to main and back again.
        'sendReceive': []
    }
};

contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods.
    'ipcRender', {
        // From render to main.
        send: (channel, args) => {
            let validChannels = ipc.render.send;
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, args);
            }
        },
        // From main to render.
        receive: (channel, listener) => {
            let validChannels = ipc.render.receive;
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender`
                ipcRenderer.on(channel, (event, ...args) => listener(...args));
            }
        },
        // From render to main and back again.
        invoke: (channel, args) => {
            let validChannels = ipc.render.sendReceive;
            if (validChannels.includes(channel)) {
                return ipcRenderer.invoke(channel, args);
            }
        }
    }
);

如果您需要帮助来了解 IPC 通道的实现以及如何在主线程或渲染线程中发送/接收它们,那么只需提出一个新问题即可。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage