How to read config file in electronjs app - electron

It's my first time using Electron JS and nodejs. I've built a small app that reads some records from a database and updates them. Everything is working fine. I have a config file with the database credentials but when I build a portable win app, I cannot figure out how to read the config file that I would like to place next to the exe. I would like to have easy access to the file, so I could run the same app on different databases.
Can anyone tell me if what I want is possible and how? I already tried to get the exe location but I couldn't. I also read a lot of topics here but nothing seems to solve my problem (I might be doing something wrong).
I'm using electron-builder to build my app.
Thanks in advance.
Edit #1
My Config file is
{
"user" :"X",
"password" :"X",
"server":"X",
"database":"X",
"options":
{
"trustedconnection": true,
"enableArithAbort" : true,
"trustServerCertificate": true
}
}
This is what I've and works when I run the project with npm start
const configRootPath = path.resolve(__dirname,'dbConfig.json');
dbConfig = JSON.parse(fs.readFileSync(configRootPath, { encoding: 'utf-8' }));
However, when I build it, the app is looking for the file in another location different from the one where the executable is.

Use of Electron's app.getPath(name) function will get you the path(s) you are after, irrespective of which OS (Operating System) you are using.
Unless your application writes your dbConfig.json file, it may be difficult for your user to understand exactly where they should place their database config file as each OS will run and store your application data in a different directory. You would need to be explicit to the user as to where to place their config file(s). Alternatively, your application could create the config file(s) on the user's behalf (automatically or through a html form) and save it to a location 'known' to the application.
A common place where application specific config files are stored is in the user's application data directory. With the application name automatically amended to the directory, it can be found as shown below.
const electronApp = require('electron').app;
let appUserDataPath = electronApp.getPath('userData');
console.log(appUserDataPath );
In your use case, the below would apply.
const electronApp = require('electron').app;
const nodeFs = require('fs');
const nodePath = require('path');
const configRootPath = nodePath.join(electronApp.getPath('userData'), 'dbConfig.json');
dbConfig = JSON.parse(nodeFs.readFileSync(configRootPath, 'utf-8'));
console.log(configRootPath);
console.log(dbConfig);

You can try electron-store to store config.
Electron doesn't have a built-in way to persist user preferences and other data. This module handles that for you, so you can focus on building your app. The data is saved in a JSON file named config.json in app.getPath('userData').

Related

How to get the current path of an electron js portable app?

Hello fellow developers/programmers. Today I come to ask for help with something, and is that I'm making an app that if or if it has to be portable, the problem I'm having is that when writing a zip file the app does not find the directories or generates the zip corruptly.
My code that writes the zip file looks like this:
ipcMain.on("report-file", async (event, data) => {
let zipFilePath = "report.zip"
let output = fs.createWriteStream(zipFilePath);
let archive = archiver("zip")
archive.pipe(output);
if (data.saves) {
archive.directory(`game/saves`, false)
archive.directory(`game/cache`, false)
}
archive.append(fs.createReadStream(`log.txt`), {
name: `log.txt`,
})
archive.append(fs.createReadStream(`traceback.txt`), {
name: `traceback.txt`,
})
archive.finalize()
});
Electron Version: 21.2.3
SO: Windows 11
electron-builder Version: 23.6.0
Looking a little more in depth, I found that the app is using the address
C:\User\User\AppData\Local\Temp\[id]\resources\app.asar
and it is trying to compress the files as if they were in that path, however, the files to compress are located where the .exe is. (G:\myapp\dist)
I already tried to fix it by following an old post on the stackoverflow page, however, it didn't solve the problem, so today I decided to ask my question here, do you have any idea how to get the actual path of an electron js portable app?
I found the solution to this, and it was to create a dialog with electron, and load the folder location. Then use resolve together with the address of the executable, this way it loads correctly the address of the folder where the exe is located.
let dir
dir = await dialog.showOpenDialog(win, {
properties: ['openDirectory'],
defaultPath: path.resolve('.', process.env.PORTABLE_EXECUTABLE_DIR)
});

cordova-plugin-file: files not accessible after app update (iOS)

I am experiencing a funny problem: I am developing an ionic app, using cordova-plugin-file to store images. The resulting paths (URIs in form file:///...) are stored in a SQLite DB along with more information. When I install the app and use it, all works perfect. But if I update (or reinstall) the app, the old images are not found anymore, while newly added images work perfect.
I first suspected that the image files were being deleted on update, but I checked the content of the directory and the files are still there. (FYI: I am using file.dataDirectory/scans/ to place my files).
Then I thought that maybe I could go around the problem loading into img src a base64 blob loaded with cordova.file.readAsUrl(), but cordova.file does not find the file as well (I insist, the files are there, I checked with XCode).
So I checked further with cordova.file and it only finds files that are added after last app install, but the older files are still present in the directory.
Here my code:
private getImgSrcFromDocument(doc: Document): any {
const uri = doc.fileName;
const src = this.webView.convertFileSrc(uri);
const sanitized = this.sanitizer.bypassSecurityTrustUrl(src);
console.log({uri, src, sanitized});
return sanitized;
}
<img class="document_thumbnail" [src]="getImgSrcFromDocument(doc)">
I have already checked this, but is not my case.
By the way, the same code works perfect on Android.
Any idea what could be the problem?
Thanks in advance!
I found the reason why and the solution (very obvious when you know the problem):
Reason
On every new install, iOS renames the data directory for the app. The directory path has this form:
file:///var/mobile/Containers/Data/Application/ABC0000-1234-99DD-00FA-E835FEA/Library/NoCloud/
The hash in the middle is renewed on every install, so the stored full paths in DB are not valid anymore.
Solution
If you still can do it (no deploy yet, no real users), store only the relative path and complete it every time with this.file.dataDirectory (or wherever you wanted to store your files).
If you already have real users and want your update to 'find the files', just ignore the first part of the stored path and build it like before:
const ValidUri = this.file.dataDirectory + // The injected cordova-plugin-file
'relativeSubDirectories/' + // If you store your files in some subdirectory
this.document.storedFullPath.substr( // Take from fullPath only the filename
this.document.storedFullPath.lastIndexOf('/') + 1
);
Where storedFullPath is the string file:///var/mobile/....
After that, you still have to do the webView conversion and the sanitizing, like in the question above.
Hope this helps someone.

Using Grails to store image but could not store outside CATALINA_HOME in production

I'm using Grails 2.5.6 to store uploaded images to folder on a server.
The following are my code to store the image
mpr.multiFileMap.file.each{fileData->
CommonsMultipartFile file = fileData
File convFile = new File(file.getOriginalFilename());
file.transferTo(convFile);
/** Processing File **/
File uploadedFile = new File("${directory}${generatedFileName}.${extension}")
convFile.renameTo(uploadedFile)
}
I have no problem running on development (MacOSX High Sierra)
But when i deployed on production (Ubuntu 14.04 server), i could not save the file outside CATALINA_HOME directory.
I have checked the permission and ownership of the destination directory, but still, the directory was created but the file was never stored.
For Example, i've tried to store the file on /home/tomcat/ directory (/home directory was in separate partition with tomcat which stored it /var), the directory was created, but the file was never stored.
When i put the destination directory within CATALINA_HOME folder, everything works fine. But this was not the scenario i want to do.
You say your destination directory is on another partition, so maybe another filesystem is used on this partition.
Or if you look on the javadoc of the renameTo method it is said :
Many aspects of the behavior of this method are inherently
platform-dependent: The rename operation might not be able to move a
file from one filesystem to another, it might not be atomic, and it
might not succeed if a file with the destination abstract pathname
already exists. The return value should always be checked to make
sure that the rename operation was successful.
...
#return true if and only if the renaming succeeded;
false otherwise
Thus I think the renameTo method is not able to move the file, don't know why but you can rewrite your code like this :
mpr.multiFileMap.file.each{fileData->
CommonsMultipartFile file = fileData
File uploadedFile = new File("${directory}${generatedFileName}.${extension}")
// String originalFilename = file.getOriginalFilename()
// you can store originalFilename in database for example
if(!uploadedFile.getParentFile().exists()) {
uploadedFile.getParentFile().mkdirs()
// You can set permissions on the target directory if you desired, using PosixFilePermission
}
file.transferTo(uploadedFile)
}

Client configuration in Electron

I am quite new to Electron and I have two questions regarding configuration of my app.
1) Looking for a way to store client configuration (similar to app.config of .Net Apps).
Why I need this:
I am working on a desktop electron app. This app will be distributed to a number of machines and each of them need to have different configuration values.
2) Need a way to package electron app with predefined configuration for a specific machine.
Example:
Machine 1's config: MachineID='M01', MachineType='A'
Machine 2's config: MachineID='M02', MachineType='B'
Appreciate the support!
For me it was the same but I needed to save settings about the window so I made a settings.js file and stored my settings in there.
For you your settings file would contain something like this:
exports.machineType = 'A';
And you would get it in your app like this:
var settings = require('./settings.js');
var machineType = settings.machineType;
if (machineType == 'A') {
// Do things for machine type A.
} else {
// Do things for machine type B.
}

Save Lokijs DB in Electron

there is some way from inside the "main.js" electron to save a file out of the asar?
I'm fighting with this command to point the way out of the write-only area but I can not do it.
It would be nice that the path was inside /my-project/resources/ and would work even without the electron-package.
let configFilePath = `${__dirname}/../config.json`
db = new loki(configFilePath)
if(fs.existsSync(configFilePath))
db.loadDatabase()
Attempting to write a file within the application installation directory is a bad idea, often the user will not have the permission to do so. Instead you should write files to the location returned by app.getPath('userData').

Resources