How to remove clutter from PyInstaller one-folder build? - python

Alright, so I managed to use PyInstaller to build a homework assignment I made with Pygame. Cool. The executable works fine and everything.
Problem is, alongside the executable, there is so much clutter. So many files, like pyds and dlls accompany the exe in the same directory, making it look so ugly.
Now, I know that these files are important; the modules I used, such as Pygame, need them to work. Still, how do I make PyInstaller build my game, so that it puts the clutter into its own folder? I could just manually make a folder and move the files in there, but it stops the exe from working.
If this info would help any, I used Python 3.4.3 and am on Windows.

Apparently this is an open request for pyinstaller, but hasn't happened in the past two years.
My workaround for this one was to create a shortcut one folder higher than the .exe folder with all the files.
The difficult part here is to set up the shortcut to work in all PCs. I did two things in the shortcut properties.
Delete the "Starts in:" path
Set as the "Target": "%windir%\system32\cmd.exe" /c start "" "%CD%\YourFolder\YourEXE.exe"
The second one calls a command line and launches your exe with a relative path. I have only tested it with windows 7. The downside is that this becomes a shortcut to the command line and you get a console window.
A different option is to create a batch file in the one folder higher than the .exe and call it. This shows only briefly the console window, but won't allow you to set your own icon. A sample code that launches your code:
#echo off
setlocal enabledelayedexpansion enableextensions
set CDir=%~dp0
set EXEF=%CDir%MyEXEFolder\
cd %EXEF%
start "MyCode" "MyCode.exe"
exit
Just open a notepad, add the code and save it as a .bat file.
This answer also describes a workaround with py2exe, but a similar approach can be used in pyinstaller. However, I find this quite "ugly" and I am not sure if it's that easy to collect all dependencies in one folder.
There is also Relative, but I didn't want to use another program.

Not trying to dig up this old question, but this was at the top of my Google search so it may be for others as well.
If you intend to distribute the program in some kind of folder, you can always just mark everything unnecessary as hidden in Windows, and it will remain hidden even if you compress or extract it.
For a program that I designed to be very user friendly, I just selected each file and folder that was not necessary to the user and hid them. If the user has show hidden files on (rarely default), they aren't likely to be intimidated by the mess of files that pyinstaller creates.

Related

How to encrypt and convert my python project to exe

I have created python desktop software. Now I want to market that as a product. But my problem is, anyone can decompile my exe file and they will get the actual code.
So is there any way to encrypt my code and convert it to exe before deployment. I have tried different ways.
But nothing is working. Is there any way to do that?.Thanks in advance
This link has most of the info you need.
But since links are discouraged here:
There is py2exe, which compiles your code into an .exe file, but afaik it's not difficult to reverse-engineer the code from the exe file.
You can of course make your code more difficult to understand. Rename your classes, functions to be non-sensical (e.g. rename print(s) to delete(s) or to a()) people will have a difficult time then.
You can also avoid all of that by using SaaS (Software as a Service), where you can host your code online on a server and get paid by people using it.
Or consider open-sourcing it :)
You can install pyinstaller per pip install pyinstaller (make sure to also add it to your environment variables) and then open shell in the folder where your file is (shift+right-click somewhere where no file is and "open PowerShell here") and the do "pyinstaller --onefile YOUR_FILE".
If there will be created a dist folder, take out the exe file and delete the build folder and the .spec I think it is.
And there you go with your standalone exe File.

PyCharm/Pyinstaller - How to optimize distribution

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.

Pyinstaller onedir option - exe file outside the directory

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.

Turn simple python program into standalone windows executable

OK, I've written a stupid simple little python program called Coloriffic that lets you adjust values of red, green, and blue and display the resulting color. I used Pygame to accomplish this.
I then looked around for how to turn that into a simple program I could give to someone else without them needing to have Python or Pygame installed. After reading of a few options (and several pieces of advice on this very site), it seemed that most people recommended cx_freeze so I downloaded the WHL and installed it. I built a setup.py script, which wasn't hard as Coloriffic has no images or other external files, and is a very simple program.
When I ran the setup.py, it worked! It created a Coloroffic.exe that ran just fine. The problem is, it also created a directory with a hundred other support files. I tried creating an MSI installer, which did give me a single executable, but one that when run simply drops the same hundred+ files in another directory.
Is there a way to take my utterly simple Coloriffic.py program and convert it into a single Windows exe file that has everything it needs INSIDE the exe and that doesn't need to be installed? I'm trying to figure out if in Python I can take my .py programs and compile them into single executables without creating a directory of support files?
If so, how do I do that?
Thanks.
EDIT: Not looking to make it closed source, just looking to gather up everything in a single file. Also, I read that "py2exe will make the exe file you want but you need to have the same version of MSVCR90.dll on the machine you're going to use your new exe" - that could be a problem, unless all Windows machines from 7 on have this file all in the same version? This is the very reason for me asking this is the first place, to create a fully independent EXE file. I also see some people recommending cx_freeze, but either they don't understand that it doesn't create a single file, or I don't understand how to make it. Is there a way to make cx_freeze create a single standalone exe?
I guess I can hope that the MSVCR90.dll dependency has been done away with and try py2exe - but I would love some advice before I go down that road if it's the wrong one.
Thanks for the suggestions and the links to other answered questions, but I still don't see a straight answer to this one?
EDIT2: One more note, when I use cx_freeze to create the executable, and then I run Coloriffic.exe, first it creates what looks like a black Dos-box window, then a second window pops up with my program. I would also like for the executable to launch just ONE window, my program, without a Dos type window coming up first and remaining up behind the program window. Thanks.
Try Py2exe, this is a pretty easy and fast approach:
Py2exe Tutorial
exe has not to be installed, but it also creates support files in the same directory

Single EXE to Install Python Standalone Executable for Easy Distribution

I used Pyinstaller to create a standalone exe file for a PyQt project. I did not use the single file option because the exe that is created with the single file option takes too long to open. Therefore, Pyinstaller created a dist folder that contains a bunch of files including my program.exe file. I would now like to create a setup.exe file that will place the contents of my dist folder in the program directory and create a shortcut in the start menu and on the desktop. I want it to be super simple for the user. Maybe like the setup.exe files that you get when you download a program from CNET. I found Inno-setup, which looks promising. However, I do not know if there any special considerations because the program is a standalone program create from a python/PyQt program. Thanks! Anyone have experience with this task? Is there a program everyone is using for this task that I do not know about?
Inno-Setup or NSIS are probably the easiest to use. You just tell them what files to include and where to put them and then they will create a nice installer for you. I wrote a short tutorial on my experiences using InnoSetup that you might find helpful:
http://www.blog.pythonlibrary.org/2008/08/27/packaging-wxpymail-for-distribution/
Note that this tutorial was based around a wxPython app I wrote, but the concepts are the same.

Categories

Resources