PyInstaller CLI can't use added binary (an .exe) even though I have added it with –add-binary flag (Windows)

Question:

Using Windows, I have a python program that runs CMD within using subprocess.Popen. When I run it from python, it works. When I create the executable and run it, it doesn’t find the tool I am using (esptool):

'esptool' is not recognized as an internal or external command,
operable program or batch file.

The command call I have built so far with --add-binary is as follows:

pyinstaller -F main.py -n "ProgramTest" -i resources/ico/icon.ico --add-binary "C:\Users\<my_user>\AppData\Local\miniconda3\envs\this_env\Scripts\esptool.exe;."

(I have obtained the path to esptool by running where.exe esptool. That’s the only instance of esptool that appears.)

Also tried the solution listed here, where they use = after the flag (--add-binary="...") and using lib as in --add-binary="...;lib".

Perhaps it has something to do with my python environments? Maybe I am not adding correctly the executable?

The code to execute my cmd lines is as follows:

import subprocess

def execute(cmd):
    popen = subprocess.Popen(
        cmd, shell=True, stdout=subprocess.PIPE, universal_newlines=True
    )
    for stdout_line in iter(popen.stdout.readline, ""):
        yield stdout_line
    popen.stdout.close()
    return popen.wait()

My environment:

  • OS Name: Microsoft Windows 10 Pro
  • Version: Windows 10.0.19045 Build 19045
  • miniconda: 23.1.0
  • Python (env): 3.10.9
  • PyInstaller: 5.8.0
  • esptool: 3.1
Asked By: Daniel Azemar

||

Answers:

Same problem as adding data, you must create a relative path to the .exe.

To be able to run the command in both an .exe and as a python script, I used:

def get_exe_path(exe_name):
    if getattr(sys, "frozen", False):
        application_path = os.path.join(sys._MEIPASS, exe_name + ".exe")
    else:
        application_path = exe_name
    return application_path

Now, just by appending it at the beggining of the call I want to call, it works:

ESPTOOL_PATH = get_exe_path("esptool")
order = ESPTOOL_PATH + " --port " + port + " --chip esp32 erase_flash"
Answered By: Daniel Azemar