I have finished my python project and now want to transfer the project into one file, so a user can just double click it and doesn't have to compile it first.
Therefore, I wanted to know if this is possible with python.
I 've read that you can convert a single python script into an executable file using pyinstaller. But in my case I have many files in different folders and I want them to be include in the executable file because otherwise the programm doesnt work.
I also tried this via the auto-pyto-exe converter (https://github.com/brentvollebregt/auto-py-to-exe) but I didnt got the results I wanted.
Therefore, my question is, how can I convert my visual studio python-project with many different files and folders into one executable file, so a user can just double click the file to start it?
Edit
In the other folder are also .py files like some FileImport.py or View.py. I separated these files that the whole project looks cleaner.
The Folder structure looks as follows:
-Views
---MainView
---UpdateView
---AnotherView
-Controllers
---MainViewController
---UpdateViewController
-Model
---MainModel
I found the solution. As it appears the pyinstaller can find all dependencies when you compile your script via pyinstaller myscript.py. PyInstaller creates three different folders where all necessary files are located. In the dist folder one executable is located which can be used from computers without python installed.
I hope this helps somebody who has the same problem.
Related
I've seen this post about a similar problem but I dont understand the solution. And I am using python 3 the other person is using python2
Link to post: Making a standalone .exe file of a python script
I made a python exe that uses multiple files.
When all the files are in one directory the exe works.
Now i put some order in my directory.
E.G. making a source folder where my sources are
making a script folder where my scripts are
Using an IDE the scripts still run, so the relations aren't wrong.
my directories look like this:
"main
main.py
sources
sources.py
buttons.py
scripts
scripts.py"
I converted main.py to exe with pyinstaller
I made an error. Went to far up the tree to find the spoken of files.
I Created a Program That Has 2 .py files.
I Want To Make The Program a .exe file, I do it using cx_Freeze.
My Problem Is That I Convert The main.py To .exe but The Second Python File Is Still a .py File.
I Don't Want It Be a .py Because If It Is The User Can See The Code.
If I Also Convert The Second Python File The Program Doesn't Work Because I import The Python File In The Main File.
Any Suggestions?
(I Don't Want To Copy The Second Python File To The Main Python File)
You are chasing the wrong rabbit here. The various tools that generate executable files from Python code are not compilers. They are just tools that embed a Python interpretor with py (or pyc) files to allow users to use the program without a prior Python installation.
Said differently you should not use them to hide your code (except from people not knowing a lot of Python): a pyc does not contain text code but according to the answers to Is it possible to decompile a compiled .pyc file into a .py file? , tools exists that convert back a pyc file into a py file (of course except the comments).
IMHO, you should better google for python obfuscate to find tools dedicated to obfuscation, what neither cx-freeze nor pyinstaller are.
BTW while there are appropriate use cases for obfuscation you should be aware that a determinate attacker can always circumvent it. The reason why the real protection for intellectual property is law and not technics...
I'm not sure how two or more .py files can be converted to .exe.
But in python the easiest way to convert to .exe is a module named pyinstaller .
You can install it using command pip install pyinstaller can get it . After just go to the directory where your project files are and open command prompt in that directory and execute pyinstaller file_name
I developed my code using PyCharm and am using PyInstaller to create a desktop .exe application. I am able to create the application, however, my current method requires navigating multiple directories, and to copy/paste some file dependencies. The whole reason to use PyInstaller was to make it more user-friendly, and easy to access the file dependencies. My question is, how should my code be organized so that a general user can easily access the file dependencies, and developer not need to copy/paste the dependency?
Below is my generalized current approach and the result.
To develop using PyCharm, edit:
/projectFolder/main.py,
/projectFolder/helper.py,
/projectFolder/data.xlsx
To create application using PyInstaller:
in command prompt, /projectFolder/venv/Scripts, execute pyinstaller ../../main.py
This creates projectFolder/venv/Scripts/dist/main/main.exe, among many more files (generated by PyInstaller) that the user shouldn't interact with or even see.
At this point, I need to copy/paste /projectFolder/data.xlsx into /projectFolder/venv/Scripts/dist/main for the .exe application to function.
The executable is now ready to be used.
I am looking for a better approach, where the user will see only the relevant files, main.exe and data.xlsx (since this will be modified, periodically). Also, I'd like data.xlsx need not be copy/pasted.
Again, how should I organize my code / package the distribution in order to simplify things for the user?
You can add files or even a folder to install with PyInstaller by using the command --add-data. The documentation explains the format for the file / folder to add but in your case it should be:
pyinstaller --add-data "data.xlsx;." main.py
Now your 'data.xlsx' will automatically copied and pasted into the folder with your .exe file.
PyInstaller also has a feature to compress all your files into one single .exe (including added data) and then when you run your program, it creates a temporary folder in your OS temp folder, usually C:\Users\USERNAME\AppData\Local\Temp\ that starts with _MEIxxxxx where the xxxx is a randomly generated number so your exe programs wont interfer with each other if more than one is running at a time. The folder is automatically deleted upon successful exit of the program.
The code to have only one file instead of a folder:
pyinstaller --onefile --add-data "data.xlsx;." main.py
There are 2 issues with having one file instead of a folder. The first isn't too big of a problem, but everytime your program crashes or doesn't close properly, the temp folder _MEIxxxxx where all your program was unloaded to wont get deleted, potentially clogging up their system. A simple fix would be to add some extra code into your program that checks if there is already a _MEIxxxxx folder with an older date/time in their temp folder and delete it.
The second is that if your program requires to read / write to a file, the code will check in the current directory of the exe, not the temp folder that is created. A workaround to this would be to write some extra code that looks for the a folder that starts with _MEI in their temp and uses that as the path. If it finds more than one folder with _MEI it should take the most recent (and hopefully delete the older ones)
Another cool feature is adding the --runtime-tmpdir command to your pyinstaller which allows you to specify the where you want your _MEIxxxxx to unload, potentially making it easier to check where the data and files you need to run the program.
pyinstaller --onefile --runtime-tmpdir "C:\TemporaryFolder" --add-data "data.xlsx;." main.py
Unfortunately, if you specify a folder or a path that doesn't exit your program wont work at all, so I would recommend creating a separate setup.exe that creates that folder for them and that should be run before running the main.exe file. Afterwards they can delete the setup file and their program should be running.
Stack Overflow has many questions about
How to give someone else a python script protecting the source code
How to compile python files
How to create packages and deploy the code
But I could not find the answer to my problem:
I want to give someone else my python script, without giving him the source code. My current attempt is compiling the file and giving away the .pyc file.
This is for sure not the best solution. Moreover, my code is made by different files. To offer a single executable pyc file, I put the code all together in a single file before compiling it: a true hell for a developer
How can I obtain my goal in a cleaner way?
Side-notes
I know .pyc files are not going to hide so much, but it is for sure better compared to giving .py files
Still, .pyc files can be incredibly problematic (as they can be system-dependant)
You can create a .exe file using pyinstaller.
pip install pyinstaller
then, open terminal in your source code directory and use the command:
pyinstaller --onefile source.py
If you have database connection with python file then it can be added using:
pyinstaller --onefile --add-data 'database.db:.' source.py
Here, :. shows database.db is a source data file and it will copy on the top level of your python application.
using "pyinstaller sroucecode.py --onefile" command will generate an executable file on Windows. This can be a way should it be desired to ship the functionality but hide the code.
There is tool, which might help you to achieve described outcome, but only if destination machine is able to run .exe files.
Recently I was experimenting with pyinstaller to create an executable file from my Python script. Everything works as expected.
I tested two options: --onefile, which takes quite a long time (like 20-30sec) to start because it depacks everything into a temporary directory.
The --onedir option is much faster (4sec) to start but it's not very comfortable to use. When I move exe file outside this directory program no longer works.
My question is: is there a possibility to make the exe file point to this directory location? I want to keep all the pyinstaller files in one place and allow users to have the exe file in any location they want.
Thanks for help.
Let's just see a real-life production case. Whenever you download say a pirated game, or and original copy of software, generally they are compressed together. When you unzip them, a new folder is extracted and inside that folder there are a lot of other folders. What you do to run the software is you simply double click the .exe file.
Your situation is the same. If you move the exe file outside the original extracted folder then it simply doesn't work. So, the work around way is to create a shortcut to the exe file.
Hope this clarifies your doubt :)
Shortcut. Create .exe shortcut. This way original .exe will be still in parent directory but shortcut can be placed anywhere
Most of the answers are about creating shortcuts, but its not the true solution. What we want is a clean folder having one dir and the exe outside that dir.
Unfortunately this is not possible at the moment. This issue is there since 2010 and was not fixed till date. Here is the link to that issue:
https://github.com/pyinstaller/pyinstaller/issues/1048
All they say is to create your own bootloader.
Nobody was able to give the PR for that.
I also found a blog on separating the exe from onedir with a hook file. I tried this but was unsuccessful with the latest version of Pyinstaller.
At last you have to do something hacky.
I found a way to do this:
Make a folder Modules in the same directory where executable is present.
Copy and paste all the heavy modules inside that folder.
Add the search path for that module folder inside your program:
# add this code in the top (before imports)
if getattr(sys, 'frozen', False):
app_path = os.path.join(os.path.dirname(sys.executable),"Modules")
sys.path.append(app_path) # search this path for modules
Under pyinstaller option --exclude-module, write the names of all those modules you excluded.
Use the one-file option but don't pack any other assets like images. Add all those external assets/folders outside.
Add this option: --runtime-tmpdir "Temp". With this, the executable will unpack the required files in the same directory under a new folder "Temp".
That's all, now you will get a very small sized exe file with mainly two required folders "modules" and the "temp". The booting time will also increase, and it will look a lot cleaner.
I think you should have some other files which is being required by that exe file & hence when you move exe file outside of directory it's giving you error. One of the example can be that the exe program require chrome driver & you have placed it within that directory. If you move exe program outside then you need to place the chrom driver also in the new position. I hope it will help you to detect , otherwise we can use exe program anywhere if it does not require any dependency of other files.
A workaround allowing a clean folder structure for the user that only contains the main exe and the libs folder is to create a second Python program containing only one instruction : call the executable of the main Python program within the over-crowed folder with libs. The main program being distributed without the --onefile option, the execution remains faster.
The principle is simple : create a new Python project with a single script your_program_launcher.py with this content :
import os
if __name__ == '__main__':
os.chdir(".{0}your_program_folder".format(os.sep))
os.system("your_program.exe")
The script is very simple and limit itself to move on the main program folder (to avoid resource access problems) and call the main program executable.
You just have to distribute this launch program with --onefile and possibly an icon (pyinstaller -i icon.png --onefile your_program_launcher.py) but this script doesn't use any libs (except os) so this executable will be very light and its execution immediate. Then you will have to put this program in the parent folder so you get a clean folder with this launch executable and the folder containing libraries and main program exe, without using a .bat file which is less natural.
dist
| your_program_launcher.exe
|
|____your_program_folder
| |_____lib1
| |_____lib2
| |_____libn
| | your_program.exe
Since the file is still an executable that needs the files in the subfolder, the user won't be able to move this executable anywhere he wants, but at least the user won't be lost in the folder containing all the libraries.