I'm trying to bundle my Python codebase into an .exe file using pyinstaller.
My code executes a shell command using nmap. This works fine in development because I have nmap installed separately on my dev environment.
However, if I want run this as an exe on another machine (without installing nmap separately on that machine) I can't seem to do this.
I've looked into the --add-binary option of pyinstaller and this is how I'm using it:
pyinstaller --onefile --add-binary "C:\Program Files (x86)\Nmap\nmap.exe";. --paths=path_to_my_python_file python_file_to_run -n name_of_my_exe_file
The resulting exe file is able to import Python specific dependencies and execute all the other Python code without any difficulties but it cannot run the nmap shell command.
This is how I'm running nmap through Python (full command omitted for brevity):
subprocess.Popen(["powershell.exe", "nmap" )],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- Is it even possible to bundle nmap with my exe file?
- If yes, am I doing it correctly?
- If not, what are my options? (I can't use any python based nmap libraries like python-nmap etc.)
[UPDATE] Working Solution: Final pyinstaller statement:
pyinstaller --paths=path_to_my_python_file --noconfirm python_file_to_run --noconfirm -n name_of_exe_file
Used robocopy to copy all the nmap files I needed:
robocopy path_to_nmap_source_directory path_to_installation_destination_directory /COPYALL /E /NFL /NDL /NJH /NJS /nc /ns /np
Python code (Bundling data files with PyInstaller (--onefile)) to get execution path of nmap:
def get_base_path():
base_path = ""
if getattr(sys, 'frozen', False):
base_path = sys._MEIPASS
return base_path
def get_exe_path(file):
#file is the name of your exe file e.g nmap.exe
base_path = get_base_path()
exe_path = os.path.join(base_path, file)
return exe_path