Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert the tool into an executable file for Windows #16

Open
valentinitnelav opened this issue Dec 23, 2022 · 1 comment
Open

Convert the tool into an executable file for Windows #16

valentinitnelav opened this issue Dec 23, 2022 · 1 comment
Labels
documentation Improvements or additions to documentation

Comments

@valentinitnelav
Copy link
Owner

valentinitnelav commented Dec 23, 2022

Convert the python scripts into a standalone executable to run the tool with the implemented GUI.

For inspiration:

I'll have to execute this on the Windows virtual machine, because if the operation runs under Linux, then it produces an executable for Linux.

@valentinitnelav
Copy link
Owner Author

valentinitnelav commented Dec 27, 2022

How to use PyInstaller

I used the PyInstaller - see documentation here https://pyinstaller.org/en/stable/usage.html

Here are the steps that I took.
On the Windows virtualbox, in the command prompt (~terminal) I did the followings:

# Move to the Documents folder
cd C:\Users\%USERNAME%\Documents

# Make a new directory there:
mkdir boxcel_exe
cd boxcel_exe

# One needs to create a Python environment so that PyInstaller works properly. 
# Idea suggested at https://stackoverflow.com/a/60789588
# Create a Python environment named "env":
python -m venv env
# Activate the environment
env\Scripts\activate.bat

# Install the needed packages so that PyInstaller packages them as well
(env) >pip install pandas
(env) >pip install Pillow
(env) >pip install xlwings
(env) >pip install pyinstaller

# FYI - list all installed dependencies. 
# Some of the installed packages above install their own dependencies too.
(env) >pip list
Package                   Version
------------------------- ---------
altgraph                  0.17.3
future                    0.18.2
numpy                     1.24.0
pandas                    1.5.2
pefile                    2022.5.30
Pillow                    9.3.0
pip                       22.3.1
pyinstaller               5.7.0
pyinstaller-hooks-contrib 2022.14
python-dateutil           2.8.2
pytz                      2022.7
pywin32                   305
pywin32-ctypes            0.2.0
setuptools                65.5.0
six                       1.16.0
xlwings                   0.28.6

# Clone this repository
(env) >git clone https://github.com/valentinitnelav/img-with-box-from-excel

# Make a folder that will contain the output of PyInstaller
(env) >mkdir deploy
(env) >cd deploy

# Make a single exe file (in deploy/dist)
# https://pyinstaller.org/en/stable/operating-mode.html#how-the-one-file-program-works
# Break the long command in multiple lines with the ^ separator (for Windows only):
(env) >pyinstaller ^
--paths "C:\Users\user\Documents\boxcel_exe\img-with-box-from-excel\src\boxcel" ^
--add-data "C:\Users\user\Documents\boxcel_exe\img-with-box-from-excel\src\boxcel\display_images.py;." ^
--onefile ^
--noconsole ^
--name boxcel ^
--debug all ^
"C:\Users\user\Documents\boxcel_exe\img-with-box-from-excel\src\boxcel\gui.py"

# --paths: the path to the folder with the python scripts
# --add-data: here the python script (that exists in --paths), but it is copied & edited at run time as if
# it is a data file.
# --onefile: tells pyinstaller to make a single exe file (saved in ./deploy/dist). The alternative, 
# by not mentioning --onefile, is to create a folder with the exe file + other needed files.
# --noconsole: tells pyinstaller to not display a console at run time when the exe file is run.
# --name: the name of the exe file
# --debug all: can help with more verbose output in the console 
# (the console that appears creating the exe file)

# Deactivate the environment
(env) >deactivate

The final folder structures is:

boxcel_exe/
├─ env/
├─ img-with-box-from-excel/
\─ deploy/
   ├─ build/
   ├─ dist/
   │  \─ boxcel.exe
   \─ boxcel.spec

Where deploy\dist\boxcel.exe is the exe file that will run the application without the need of installing Python. This file can be moved anywhere. It doesn't have to be in its current location.

Encountered errors & debugging

For debugging purposes use the --debug all option with pyinstaller. But do not use --noconsole (this option stops the console to be displayed). This can help with more verbose output in the console.
Additionally, when you test the exe file, open a command prompt, navigate to the directory containing the exe and run the exe file by typing its name, then hit Enter:

cd Documents\boxcel_exe\deploy\dist
boxcel.exe

In this way you will benefit of having error messages in a console when debugging.

Encountered errors

Missing module errors

In order to avoid missing module errors, one needs to add all the needed scripts wit the --paths argument to pyinstaller command above. Make sure to give the entire path and use the quotations.
Example of error message for missing module:

Traceback (most recent call last):
  File "boxcel\gui.py", line 13, in <module>
ModuleNotFoundError: No module named 'start_project'
[14296] Failed to execute script 'gui' due to unhandled exception!

Here it was also suggested to delete the __init__.py but this is not encouraged - see this.

Missing data or script files

If you get an error message like:

" [Error 2] No such file or directory:
'C:\\Users\\user\\AppData\\Local\\Temp\\_MEI112962\\base_library.zip\\display_images.py' 

It is because you need to include the script display_images.py as data file with the --add-data argument.

Other options & lessons learned

The advantage of producing a single exe is that it makes it easier for the user. However, it can be a bit slower when it runs and if it crashes, it will create a bunch of temp folders like C:\Users\vs66tavy\AppData\Local\Temp\_MEIxxxxxx (where xxxxxx is a random number) - https://pyinstaller.org/en/stable/operating-mode.html#how-the-one-file-program-works

The alternative is to produce a folder that can be distributed to the users by omitting --onefile (see https://pyinstaller.org/en/stable/operating-mode.html#how-the-one-folder-program-works):

pyinstaller ^
--paths "C:\Users\user\Documents\boxcel_exe\img-with-box-from-excel\src\boxcel" ^
--add-data "C:\Users\user\Documents\boxcel_exe\img-with-box-from-excel\src\boxcel\display_images.py;." ^
--noconsole ^
--name boxcel ^
--debug all ^
"C:\Users\user\Documents\boxcel_exe\img-with-box-from-excel\src\boxcel\gui.py"

@valentinitnelav valentinitnelav added the documentation Improvements or additions to documentation label Dec 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant