How to get the original path of a portable Electron app?
Asked Answered
O

8

23

I have an Portable Electron App (packed with: electron-builder + asar, portable build) on Windows. I try to get the application path but it returns a path within the user\temp folder rather than the actual '.exe' file

Is there any way to get the original app.exe path?

I've tried the following:

  • app.getAppPath()
  • __dirname
  • require.main.filename
  • app-root-path
  • and a few node modules

The path I'm getting from my tests:

C:\Users\xxx\AppData\Local\Temp\xxxxxx.tmp\app

the actual .exe Path (where the app launched from, and what i need):

C:\Users\XXX\Documents\test\dist

I'm just starting with Electron.

Overdraw answered 19/9, 2017 at 18:49 Comment(1)
I collected some path data for windows and mac - see here github.com/BananaAcid/Simple-Electron-Kiosk/blob/master/…Cetacean
O
20

I found a solution: Use the Environment Variable (created by Electron-Builder)

process.env.PORTABLE_EXECUTABLE_DIR

to show the real Path of the App.exe. Works only packed with Electron-Builder

Overdraw answered 9/10, 2017 at 12:55 Comment(4)
I'm on mac right now where this is empty..tried it in dev mode and after building :/Tribrach
on windows it seems to work..so maybe combining this for windows and the other answer (which isn't working as expected on windows) for mac and maybe linux which I still have to investigate so who receives the bounty?Tribrach
Out of curiosity is this environment variable set at all by a non portable build of the application? If not it would be a nice way for the app to be able to tell whether or not it was portable.Heerlen
Does not work anymore! PORTABLE_EXECUTABLE_DIR is undefinedObstacle
M
14

From the main process:

// If not already defined...
const { app } = require ('electron');
const path = require ('path');

let execPath;

execPath = path.dirname (app.getPath ('exe'));
// or
execPath = path.dirname (process.execPath);

From a renderer process:

// If not already defined...
const { remote } = require ('electron');
const path = require ('path');

let execPath;

execPath = path.dirname (remote.app.getPath ('exe'));
// or
execPath = path.dirname (remote.process.execPath);
Mayweed answered 4/10, 2017 at 11:44 Comment(3)
on mac it returns ../build/mac/APPName.app/Contents/MacOS which is not what we need...we could String.replace or String.split to get only the ...builld/mac part, then it would be nice to programmatically know the app names of every build because windows and linux have version numbers (maybe I just construct it from the package.json) I'll check if it yields the same on windows and linux :-)Tribrach
maybe a combination of your solution and the one from LycaKnight..but then who earns the bounty?Tribrach
For me it returned /Applications/Weaver.app/Contents/MacOS and the path required was /Applications/Weaver.app/Contents/MacOS/Weaver with Weaver being the name of my app. My tests was requiring the path, and now the test does start an instance of Electron (Weaver)Halfsole
M
6

I had a lot of trouble with this and was finally able to solve the issue by replacing __dirname with '.', see working example below :

const path = require('path')
const myAppPath = path.resolve('.', 'myapp.exe');
Myocardiograph answered 19/2, 2020 at 20:44 Comment(2)
It took me Hours to find this solution. ThanksAllure
Spent 30 minutes searching multiple responses that made no difference. This is the only solution that has worked so far. Makes no sense that it's not in the documentation.Narcolepsy
S
3

Seems like PORTABLE_EXECUTABLE_FILE only works under certain Electron-Builder configurations; In particular, it won't work in apps deployed as a portable directory.

In such cases, the following will get you the application root path:

const path = require('path')
import { app } from 'electron'

let rootDir = app.getAppPath()
let last = path.basename(rootDir)
if (last == 'app.asar') {
    rootDir = Path.dirname(app.getPath('exe'))
}
Supernova answered 30/6, 2020 at 23:9 Comment(0)
W
1

None of the above answers worked for me on Windows 10.

process.env.PORTABLE_EXECUTABLE_DIR returns the Temp directory path.

I got it to work using:

process.env.INIT_CWD
Wentletrap answered 30/11, 2018 at 9:58 Comment(0)
C
1
process.env.PORTABLE_EXECUTABLE_FILE

will give you the full path to the file.

Curry answered 25/3, 2019 at 14:22 Comment(2)
in my project PORTABLE_EXECUTABLE_FILE is undefined in DEV build. No idea whyNiall
It should be. You need to create the .exe file and then execute it for that variable to be defined.Curry
N
1

As none of the methods above worked and I don't want to use an external lib for this, i tried following:

        if (!fs.existsSync("../images")) {
            fs.mkdirSync("./../images");            
        }
        return path.resolve("./../images/") + "/";

You can use any directory that should exist at the top level or anywhere else. In my case I know that one level higher in the directory there must be a directory called "images".

This solution worked in my case for DEV build and prod (packaged).

Are there any drawbacks when using this approach?

Niall answered 26/3, 2019 at 13:10 Comment(1)
The fact that you are creating a directory outside of your application? How do you know you even have the permissions to do so?Heerlen
Q
0

I used process.env.PORTABLE_EXECUTABLE_DIR but it works only when I make the portable but when I use npm start I got undefiend, So I solve this issue by checking the node_env using the following code (process.env.NODE_ENV !== "development") ? process.env.PORTABLE_EXECUTABLE_DIR : path.dirname(app.getAppPath())

you can change the path.dirname(app.getAppPath()) by the path you want to get in the development mode.

Quartering answered 9/5 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.