I am building an Electron app for editing .txt files on a windows puter. I have used electron builders fileAssociations
to open .txt files however I cannot get the path of the file. When I looked in the Electron docs I found this which is exactly what I want except it is mac-only... is there a way to get the same functionality on Windows?
I am building an Electron app for editing .txt files on a windows puter. I have used electron builders fileAssociations
to open .txt files however I cannot get the path of the file. When I looked in the Electron docs I found this which is exactly what I want except it is mac-only... is there a way to get the same functionality on Windows?
5 Answers
Reset to default 1As Lucas Roland mentioned, you have to parse process.argv
to get the filepath
if (process.argv.length >= 2) { // or electron.remote.process.argv
let filePath = process.argv[1];
//open, read, handle file
}
The best alternative that I have found for this problem is using second-instance
event on the app
module with process.argv
.
When a user clicks a file associated with your app, on Windows (yeah! I only tried it on Windows), it will try to open a new instance of the app with the path of the related file inside process.argv
. If you are not using multiple instances of the app, then you should prevent the app from opening multiple instances of the app and try to fetch the data (mainly the process.argv
) to the main instance using the second-instance
event from the app
module.
First, you should get the singleInstanceLock from app.requestSingleInstanceLock()
to make the current instance the only instance of the app. This will return a boolean. If it returns false, this means that another instance has the singleInstanceLock. Then you should close that instance using app.quit()
.
// Behaviour on second instance for parent process
const gotSingleInstanceLock = app.requestSingleInstanceLock();
if (!gotSingleInstanceLock) app.quit(); // Quits the app if app.requestSingleInstanceLock() returns false.
If the boolean is true, then this means the current app session is the main session of the app.
Then we should use the second-instance
event of the app
module to detect second instances from that point onwards. If another instance emerges, it will be closed, but second-instance
event will be fired with the relevant arguments needed to identify what opened that instance to the process.argv
. The second parameter of the callback added to the second-instance
event can be used to get those arguments sent to that instance. From that point onwards, you can filter the strings inside the process.argv
and get the relevant path of the file that opened the other instance.
// Behaviour on the second instance for the parent process
const gotSingleInstanceLock = app.requestSingleInstanceLock();
if (!gotSingleInstanceLock) app.quit();
else {
app.on('second-instance', (_, argv) => {
//User requested a second instance of the app.
//argv has the process.argv arguments of the second instance.
if (app.hasSingleInstanceLock()) {
if (mainWindow?.isMinimized()) mainWindow?.restore();
mainWindow?.focus();
process.argv = argv; // I tried to add the argv from the second instance to my main instance.
}
});
}
Please keep in mind that arguments in process.argv
will be added differently when the app is packaged. Therefore, you should loop through the arguments and check whether an argument is a path in the system using the stat()
function in the fs
module and if it has the .txt
extension at the end using the path.extname()
I found this method the hard way, so I hope that anyone with this problem wouldn't have to go through all of that.
On Windows, you have to parse process.argv (in the main process) to get the filepath.
from https://github./electron/electron/blob/master/docs/api/app.md#event-open-file-macos
On Windows, you need to use process.argv
in the main process to read the file path. According to this answer, you can use the fs
package to open, read & write files. There are a few more ways described to do the same thing.
Also, the following snippet from this blog post might be helpful.
How to configure your app to open linked files in Windows
On Windows, you have to parse process.argv to get the file path. Then, you can use the IPC module to handle messages from the renderer process (web page) and retrieve a datastore from a file. This is how we did it:
In the main process:
var ipc = require('ipc');
var fs = require('fs');
// read the file and send data to the render process
ipc.on('get-file-data', function(event) {
var data = null;
if (process.platform == 'win32' && process.argv.length >= 2) {
var openFilePath = process.argv[1];
data = fs.readFileSync(openFilePath, 'utf-8');
}
event.returnValue = data;
});
I am not very well versed with electron
, else I would have tried to give you a better answer, but this is what I could find with my understanding about it. I hope this helps!
For windows, parsing process.argv on app ready worked for me. So in the main process somewhere:
const { app } = require('electron');
const devEnv = /electron/.test(process.argv[0]);
app.on('ready', () => {
if (process.platform.startsWith('win') && !devEnv && process.argv.length >= 2) {
const filePath = process.argv[1];
// In my app, I initialise a new window here and send filePath through
// to the renderer process so it can be read and displayed.
} else {
// Create whatever your default window is (in my case, an empty document)
}
});
On windows, this event is fired every time you open a new file even if another file is already open in the application.
Remember also that during development, we launch the application with electron .
or electron . --debug
or something similar. Because of this, I also test whether the first argument is electron
and skip over file opening logic in this case (the case that devEnv
evaluates to 'true').