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.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 2
    I collected some path data for windows and mac - see here https://github.com/BananaAcid/Simple-Electron-Kiosk/blob/master/PATH%20RESULTS – BananaAcid Aug 03 '18 at 18:06

7 Answers7

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

  • I'm on mac right now where this is empty..tried it in dev mode and after building :/ – Can Rau Oct 10 '17 at 17:17
  • 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? – Can Rau Oct 10 '17 at 17:54
  • 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. – cbartondock May 13 '20 at 01:42
  • Does not work anymore! `PORTABLE_EXECUTABLE_DIR` is undefined – leonheess Jul 14 '22 at 22:00
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);
  • 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 :-) – Can Rau Oct 05 '17 at 14:14
  • maybe a combination of your solution and the one from LycaKnight..but then who earns the bounty? – Can Rau Oct 10 '17 at 17:55
  • 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) – Mathieu Brouwers Jun 06 '18 at 12:22
4

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

const path = require('path')
const myAppPath = path.resolve('.', 'myapp.exe');
Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81
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'))
}
DanyAlejandro
  • 1,440
  • 13
  • 24
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
David J.
  • 1,753
  • 13
  • 47
  • 96
1
process.env.PORTABLE_EXECUTABLE_FILE

will give you the full path to the file.

ramaralo
  • 1,013
  • 2
  • 10
  • 15
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?

Josef Biehler
  • 952
  • 4
  • 16
  • 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? – cbartondock May 12 '20 at 20:18