最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Electron and sqlite3 issue after packaging app - Stack Overflow

programmeradmin3浏览0评论

I've asked quite a few questions on here recently as I'm continually getting stuck with varying parts of node and databases.

Anyhow, a bit of background:

I have an Electron app with an AngularJS frontend. So on the electron side of things, I actually spin up an express server which serves my angular app, which can then of course talk to electron over ipc. I'm also using the express side of things to do the database stuff (sqlite3), defining routes for an api which Angular can hit using $http and have db results returned that way. Everything works absolutely fine when I'm running the app with 'npm start'. The code for the db/server side of things is as follows:

var path = require('path');
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
var path = require('path');
var sqlite3 = require('sqlite3').verbose();

// Load the db
function createDbFile() {
    // Try to open the db file - if it doesn't exist, create it.
    try {
        var filebuffer = fs.readFileSync(path.join(__dirname, 'app.db'));
    }
    catch (err) {
        if (err.code === 'ENOENT') {
            fs.closeSync(fs.openSync(path.join(__dirname, 'app.db'), 'w'));
        } 
        else {
            throw err;
        }
    }
}

createDbFile();
var db = new sqlite3.Database('app.db');
var check;

db.serialize(function() {
db.run("CREATE TABLE IF NOT EXISTS lorem (info TEXT)");

var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
for (var i = 0; i < 10; i++) {
    stmt.run("Ipsum " + i);
}
stmt.finalize();
});

app.use(express.static(__dirname));
// app.use(bodyParser.json());

app.get('/', function (req, res) {
    res.sendFile(__dirname + 'index.html');
});

app.get('/loading', function (req, res) {
    res.sendFile(__dirname + '/loading.html');
});

app.get('/api/get/all', function (req, res) {    
    db.all("SELECT * FROM lorem", function(err, row) {
    res.json(row);
    });
});

app.post('/api/post/site', function (req, res) {
    // Do stuff here.
});

app.listen(3333);

As well as that, here's my main.js file, which requires this server.js file:

const electron = require('electron');
const server = require("./server");
const ipcMain = require('electron').ipcMain;
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

// Define our global references
let mainWindow,
    loadingScreen,
    windowParams = {
      width: 1000,
      height: 700,
      show: false
    },
    loadingWindowParams = {
      width: 400,
      height: 300,
      show: false,
      frame: false
    };

// Define our loading window whose parent is main
function createLoadingScreen() {
    loadingScreen = new BrowserWindow(Object.assign(loadingWindowParams, {parent: mainWindow}));
    loadingScreen.loadURL('http://localhost:3333/loading');
    loadingScreen.on('closed', () => loadingScreen = null);
    loadingScreen.webContents.on('did-finish-load', () => {
        loadingScreen.show();
    });
}

app.on('ready', () => {
  // Create loading screen
  createLoadingScreen();

  // Create the browser window.
  mainWindow = new BrowserWindow(windowParams);

  // Point to our express server
  mainWindow.loadURL(`http://localhost:3333`);

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Simulate loading to allow angular to initialize, then show main window
  mainWindow.once('ready-to-show', () => {
    if (loadingScreen) {
      setTimeout(function() {
        loadingScreen.close();
        mainWindow.show();
      }, 6000);
    }
  });

  // Close the app after window closed for security purposes
  mainWindow.on('closed', function () {
    mainWindow = null
    app.quit();
  });

  // Handle messages
  ipcMain.on('electron-msg', (event, msg) => {
    switch (msg.type) {
      case 'system':
        mainWindow.webContents.send('electron-msg', 'Message received');
      break;
    }
  });

});

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
});

// Open window again when activated
app.on('activate', function () {
  if (mainWindow === null) {
    // Not currently needed, we quit when window closed
  }
});

// Throw our errors
process.on('uncaughtException', function (err) {
  console.log(err);
});

The issue I'm having is that when I package my app using , the app functions, the server is spun up and the Angular ponents work fine, but I cannot read/write/create a database file like I can before packaging. I'm ultimately clueless now as to where to look!

I've asked quite a few questions on here recently as I'm continually getting stuck with varying parts of node and databases.

Anyhow, a bit of background:

I have an Electron app with an AngularJS frontend. So on the electron side of things, I actually spin up an express server which serves my angular app, which can then of course talk to electron over ipc. I'm also using the express side of things to do the database stuff (sqlite3), defining routes for an api which Angular can hit using $http and have db results returned that way. Everything works absolutely fine when I'm running the app with 'npm start'. The code for the db/server side of things is as follows:

var path = require('path');
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
var path = require('path');
var sqlite3 = require('sqlite3').verbose();

// Load the db
function createDbFile() {
    // Try to open the db file - if it doesn't exist, create it.
    try {
        var filebuffer = fs.readFileSync(path.join(__dirname, 'app.db'));
    }
    catch (err) {
        if (err.code === 'ENOENT') {
            fs.closeSync(fs.openSync(path.join(__dirname, 'app.db'), 'w'));
        } 
        else {
            throw err;
        }
    }
}

createDbFile();
var db = new sqlite3.Database('app.db');
var check;

db.serialize(function() {
db.run("CREATE TABLE IF NOT EXISTS lorem (info TEXT)");

var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
for (var i = 0; i < 10; i++) {
    stmt.run("Ipsum " + i);
}
stmt.finalize();
});

app.use(express.static(__dirname));
// app.use(bodyParser.json());

app.get('/', function (req, res) {
    res.sendFile(__dirname + 'index.html');
});

app.get('/loading', function (req, res) {
    res.sendFile(__dirname + '/loading.html');
});

app.get('/api/get/all', function (req, res) {    
    db.all("SELECT * FROM lorem", function(err, row) {
    res.json(row);
    });
});

app.post('/api/post/site', function (req, res) {
    // Do stuff here.
});

app.listen(3333);

As well as that, here's my main.js file, which requires this server.js file:

const electron = require('electron');
const server = require("./server");
const ipcMain = require('electron').ipcMain;
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

// Define our global references
let mainWindow,
    loadingScreen,
    windowParams = {
      width: 1000,
      height: 700,
      show: false
    },
    loadingWindowParams = {
      width: 400,
      height: 300,
      show: false,
      frame: false
    };

// Define our loading window whose parent is main
function createLoadingScreen() {
    loadingScreen = new BrowserWindow(Object.assign(loadingWindowParams, {parent: mainWindow}));
    loadingScreen.loadURL('http://localhost:3333/loading');
    loadingScreen.on('closed', () => loadingScreen = null);
    loadingScreen.webContents.on('did-finish-load', () => {
        loadingScreen.show();
    });
}

app.on('ready', () => {
  // Create loading screen
  createLoadingScreen();

  // Create the browser window.
  mainWindow = new BrowserWindow(windowParams);

  // Point to our express server
  mainWindow.loadURL(`http://localhost:3333`);

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Simulate loading to allow angular to initialize, then show main window
  mainWindow.once('ready-to-show', () => {
    if (loadingScreen) {
      setTimeout(function() {
        loadingScreen.close();
        mainWindow.show();
      }, 6000);
    }
  });

  // Close the app after window closed for security purposes
  mainWindow.on('closed', function () {
    mainWindow = null
    app.quit();
  });

  // Handle messages
  ipcMain.on('electron-msg', (event, msg) => {
    switch (msg.type) {
      case 'system':
        mainWindow.webContents.send('electron-msg', 'Message received');
      break;
    }
  });

});

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
});

// Open window again when activated
app.on('activate', function () {
  if (mainWindow === null) {
    // Not currently needed, we quit when window closed
  }
});

// Throw our errors
process.on('uncaughtException', function (err) {
  console.log(err);
});

The issue I'm having is that when I package my app using https://github./electron-userland/electron-builder, the app functions, the server is spun up and the Angular ponents work fine, but I cannot read/write/create a database file like I can before packaging. I'm ultimately clueless now as to where to look!

Share Improve this question edited Sep 27, 2016 at 8:40 Adam Thomason asked Sep 27, 2016 at 8:35 Adam ThomasonAdam Thomason 1,16611 silver badges24 bronze badges 3
  • 2 Dont use __dirname for db file, for production app.getPath('userData') value is more suitable. – Marius Darila Commented Sep 27, 2016 at 10:10
  • @MariusDarila Would this make a difference to the create or accessing the file when the electron app is packaged? – Adam Thomason Commented Sep 27, 2016 at 11:34
  • I removed the call to the function which creates the file as Database('app.db') does actually create the file if it doesn't exist - at least it does locally. I still can't get this to work! – Adam Thomason Commented Sep 27, 2016 at 11:42
Add a ment  | 

1 Answer 1

Reset to default 7

I've managed to fix this almost accidentally after bashing my head against my desk for a while. I was attempting to implement some logging to see whether there were issues with the node module not being recognised correctly when packaged, when I noticed the log file wasn't being created where I was expecting it to be - it was being created outside of the actual app directory and therefore was not accessible. The same thing happened with my database file.

See fix below:

var db = new sqlite3.Database(__dirname + '/app.db');

The addition of __dirname to the db file definition fixed the issue!

发布评论

评论列表(0)

  1. 暂无评论