9

If you are running a frozen python script (frozen using py2exe) from a directory and drive different from where the script is present, what is the best way to determine the path of the executing script?

Few solutions I have tried

inspect.getfile(inspect.currentframe())

Problem: Does not return the full path. It only returns the script name.

os.path.abspath( __file__ )

Problem: Doesn't work on Windows

os.path.dirname(sys.argv[0])

Problem: Returns empty string.

os.path.abspath(inspect.getsourcefile(way3))

Will not work if the drive is different from the pwd

os.path.dirname(os.path.realpath(sys.argv[0]))

Will not work if the drive is different from the pwd

Here is a minimal not-working example

D:\>path
PATH=c:\Python27\;c:\Users\abhibhat\Desktop\ToBeRemoved\spam\dist\;c:\gnuwin32\bin

D:\>cat c:\Users\abhibhat\Desktop\ToBeRemoved\spam\eggs.py
import os, inspect, sys
def way1():
    return os.path.dirname(sys.argv[0])

def way2():
    return inspect.getfile(inspect.currentframe())

def way3():
    return os.path.dirname(os.path.realpath(sys.argv[0]))

def way4():
    try:
        return os.path.abspath( __file__ )
    except NameError:
        return "Not Found"
def way5():
    return os.path.abspath(inspect.getsourcefile(way3))

if __name__ == '__main__':
    print "Path to this script is",way1()
    print "Path to this script is",way2()
    print "Path to this script is",way3()
    print "Path to this script is",way4()
    print "Path to this script is",way5()

D:\>eggs
Path to this script is
Path to this script is eggs.py
Path to this script is D:\
Path to this script is Not Found

Related Questions:

Note

@Fenikso's solution will work if the script resides on the same drive where you are executing but when its on a different drive, it will not work

Community
  • 1
  • 1
Abhijit
  • 62,056
  • 18
  • 131
  • 204

3 Answers3

12

Another approach which works with cxFreeze when running from another drive even using PATH:

import sys

if hasattr(sys, 'frozen'):
    print(sys.executable)
else:
    print(sys.argv[0])

From Python:

H:\Python\Examples\cxfreeze\pwdme.py

From command line:

D:\>h:\Python\Examples\cxfreeze\dist\pwdme.exe
h:\Python\Examples\cxfreeze\dist\pwdme.exe

Using PATH:

D:\>pwdme.exe
h:\Python\Examples\cxfreeze\dist\pwdme.exe
Fenikso
  • 9,251
  • 5
  • 44
  • 72
  • @Fenikso: This works perfectly. Before posting this question I have seen few references to the same problem in SO, but none of the answers is not correct per se'. – Abhijit Apr 24 '12 at 09:01
2

IMHO, code that acts differently depending from absolute paths is not a good solution. It will be probably better a relative path solution. Use dirname to know the relative directory and os.sep for cross platform compatibility.

if hasattr(sys, "frozen"):
    main_dir = os.path.dirname(sys.executable)
    full_real_path = os.path.realpath(sys.executable)
else:
    script_dir = os.path.dirname(__file__)
    main_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
    full_real_path = os.path.realpath(sys.argv[0])

the frozen attribute is python standard.

Take a look also at Esky : http://pypi.python.org/pypi/esky

J_Zar
  • 2,034
  • 2
  • 21
  • 34
0

Try this:

WD = os.path.dirname(os.path.realpath(sys.argv[0]))

That is what I use with cx_Freeze to get the directory from where the .exe is really running.

Fenikso
  • 9,251
  • 5
  • 44
  • 72
  • This will not work if the script is present in a different drive – Abhijit Apr 24 '12 at 08:00
  • @Abhijit - Sorry, I do not understand. This is fundamental part of all my frozen scripts and it never failed. Can you describe an example when this fails? – Fenikso Apr 24 '12 at 08:02
  • I have updated the example to include this scenario. If the drive is different, it just returns the drive name from where you are running. – Abhijit Apr 24 '12 at 08:06
  • @Abhijit - Hmmm. Actually that is the use of PATH what changes the behavior. And the way 2 is actually kind of working for me with cxFreeze. – Fenikso Apr 24 '12 at 08:13
  • Can you please amplify as to what do you mean by `And the way 2 is actually kind of working for me`. Are you saying that this will work even if the drive is different? – Abhijit Apr 24 '12 at 08:19
  • I made a mistake. It returns `h:\Python\Examples\cxfreeze\pwdme.py` instead of `h:\Python\Examples\cxfreeze\dist\pwdme.exe`. Note the directory. – Fenikso Apr 24 '12 at 08:25