'How to release an application write by Python (which has structure folder) to user

I am new with Python and I write application for testing by Pycharm. My application has structure folder and I want to release build package for manual tester to run it. My folder structure as below:

Actions\Common.py
Actions\DB.py
Form\DualTestObject.py
Configuration\Interface.txt
Configuration\Setting.txt
Testcase\ImageCapture.py
Testcase\OCRTestCase.py
Runbat\ImageCaptureTest.bat
Runbat\OCR.bat
Runbat\...
.main.py
I use command below to build file exe.
pyinstaller --paths = <pathtofoler>\Actions;<pathtofolder>\Form;<pathtofolder>\Testcase; C:\HHS\Runbat main.py

After building process finishes successfully. I run file main.exe in folder dist\main, the program can run but it throws an error as below:

C:\HHS\dist\main>main.exe
Which testcase do you want to test
1. Image Capture
2. Reset Base
3. OCRTestcase
4. USBOEMCommand (remember turn off Vietnamese):
Please enter that number: 1
**Traceback (most recent call last):
  File "main.py", line 19, in <module>
  File "subprocess.py", line 349, in call
  File "subprocess.py", line 951, in __init__
  File "subprocess.py", line 1420, in _execute_child
FileNotFoundError: [WinError 2] The system cannot find the file specified
[22080] Failed to execute script 'main' due to unhandled exception!
C:\HHS\dist\main>**

Although I run these source by Pycharm, it runs OK.

Content of my main.py file is:

import subprocess
import os
print("Which testcase do you want to test")
print("1. Image Capture")
print("2. Reset Base")
print("3. OCRTestcase")
print("4. USBOEMCommand (remember turn off Vietnamese):")
option = input("Please enter that number: ")
current_folder = currentfolder = os.getcwd()
runbatfolder = current_folder + "\Runbat\\"
if(option == "1"):
    filebat = runbatfolder + "ImageCaptureTest.bat"
elif(option == "2"):
    filebat = runbatfolder + "ResetBase.bat"
elif(option == "3"):
    filebat = runbatfolder + "OCR.bat"
elif(option == "4"):
    filebat = runbatfolder + "USBOEMCommand.bat"
subprocess.call(filebat)

So how to overcome this issue, I think the way I import the subprocess module has the problem but I don't know how to fix it.



Solution 1:[1]

As you said, you run your main.exe from dist folder. Make sure to copy all subfolders from the location where the script is.

Just an example: if you have a script like this:

-D:/myScript/main.py
-D:/myScript/someOtherPythonFiles/script1.py
-D:/myScript/someOtherPythonFiles/script2.py

Your path from main.py to the scripts is current directory + someOtherPythonFiles + name of the script and you get D:/myScript(current location)/someOtherPythonFiles/script1.py(name of the script).

If you create an executable, and that executable is inside the dist/main folder, your path to the scripts looks like this:
D:/myScript/dist/main(current location)/someOtherPythonFiles/script1.py(name of the script) -> but you don't have it there unless you copy it there.
So final comparasion:

Location from main.py: D:/myScript/someOtherPythonScrips/script1.py
Location from dist/main/main.exe: D:/myScript/dist/main/someOtherPythonScripts/script1.py
-> Make sure you have this there

Solution 2:[2]

C:\HHS\dist\main>main.exe

current_folder = currentfolder = os.getcwd()
runbatfolder = current_folder + "\Runbat\\"
filebat = runbatfolder + "ImageCaptureTest.bat"

(Next time do: os.path.join(..). It is more stable and ensures your string is created correctly.)

This will yield:

current_folder = "C:\\HHS\\dist\\main"
runbatfolder = "C:\\HHS\\dist\\main\\Runbat"
filebat = "C:\\HHS\\dist\\main\\Runbat\\ImageCaptureTest.bat"

However looking at:

pyinstaller --paths = <pathtofoler>\Actions;<pathtofolder>\Form;<pathtofolder>\Testcase; C:\HHS\Runbat main.py

Your Runbat folder is located at C:\HHS\Runbat not C:\HHS\dist\main\Runbat.


os.getcwd() returns your current working directory. When you run main.py from C:\HHS it will return C:\HHS.
When you run your created main.exe from C:\HHS\dist\main it will return C:\HHS\dist\main.

So moving main.exe to C:\HHS\Runbat should work or you work on your pathstring.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alexandru DuDu
Solution 2 Tin Nguyen