Search code examples
pythonwindowscmdcygwin

File paths within my Python script fail when launching via double-click (Windows 10)


I have a python script that reads and writes to files that are located relative to it, in directories above and beside it. When I run my script via Cygwin using

python script.py

The program works perfectly. However, when I run it by navigating through the windows GUI to my file and double clicking, I get a blank cmd prompt and then my program runs fine until I reach the point where I need to access the other files, at which point it fails and gives me this message in the cmd prompt that opens itself:

../FFPRM.TXT                                                                                                             
../2025510296/FFPRM_000.TXT                                                                                             
Exception in Tkinter callback                                                                                           
Traceback (most recent call last):                                                                                        
  File "C:\Users\rbanks\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__          
    return self.func(*args)                                                                                     
  File "C:\Users\rbanks\Desktop\TSAC\EXECUTABLE\T-SAC_GUI.py", line 705, in run_exe                                         
    invalid_entry, output_text = self.apply()                                                                              
  File "C:\Users\rbanks\Desktop\TSAC\EXECUTABLE\T-SAC_GUI.py", line 694, in apply                                           
    p = subprocess.Popen(['cp', output_file_path, output_file_path_id])                                                   
  File "C:\Users\rbanks\AppData\Local\Programs\Python\Python35-32\lib\subprocess.py", line 950, in __init__          
    restore_signals, start_new_session)                                                                                   
  File "C:\Users\rbanks\AppData\Local\Programs\Python\Python35-32\lib\subprocess.py", line 1220, in _execute_child          startupinfo)                                                                                                        
FileNotFoundError: [WinError 2] The system cannot find the file specified 

I am deploying this script as well as the directory structure as a zip for users to be able to unzip and use anywhere on their PC, so it is important for me to be able to run it with a simple double click and my relative file paths.

My first thought was the cmd prompt that was opening and executing my script was in a different environment, but when I run:

cd
pause

in a .cmd script, I get:

C:\Users\rbanks\Desktop\TSAC\EXECUTABLE>pause 

Which is the correct location.

I am not having any luck with Google, I assume because I can't seem to construct a sufficient search query. Could someone point me in the right direction please?


Solution

  • The problem is not the current directory. It is correct when double clicking on the icon

    The problem is: Cygwin commands are not in the windows path

    You are using python, so don't run simple copy commands like this, which make your script non-portable and subject to variations, requiring installation of cygwin, etc...

    p = subprocess.Popen(['cp', output_file_path, output_file_path_id])  
    

    can be replaced by

    import shutil
    shutil.copyfile(output_file_path, output_file_path_id)
    

    shutil module complements os module for file manipulation functions that aren't native in the operating system.

    now you have a 100% pythonic solution, native, which will throw exceptions if cannot read/write files, so fully integrated in the rest of your program.

    Before running an external command from Python make sure that no python way exists. There are so many useful modules out there.

    Other examples of how to avoid running basic commands from python (of course if you need to run a C compilation it's different!):

    • zipfile package: much better than running zip.exe
    • gzip package: can open gzipped files natively from python
    • os.listdir() instead of parsing the output of cmd /c dir /B
    • os.remove() instead of calling rm or del

    etc... python rules!