I'm trying to figure out a way to create an installer for a python application that I have created an executable for using cx freeze. I'd like to be similar to the windows standard installation wizard, but I would also like to be able to customize it as much as possible (removing windows, adding logos where the standard blue windows computer is, etc.).
The major requirments are:
needs to be able to install .Net (and possibly other dependencies)
needs to be able to add program to start-up processes
look and feel (logos, banners, etc.) need to be able to be customized
I've tried Inno Setup, and while this gets my pretty close to what I want but does not give me some of the customization I need.
A good example of installation wizards I'm trying to replicate would be the ones for Firefox or Chrome.
I know that I can create a custom installation wizard for this sort of thing from scratch if needed. I just wasn't sure if something already existed for this, or if there was some utility that would allow me to do this.
I developed a Python/GTK/OpenGL based desktop application in the past and in order create the executable and an installer I've used PyInstaller + NSIS.
NSIS is what you're asking for: it's quite flexible, you may want to give a try.
Related
Dear community members,
I would like to have your opinions about my situation. I wrote some python modules to simplify the daily routine at work. I'm the only 'developer' and the user community is a handful of people with limited computer skills. The scripts should be available on several computers (Windows 7, 10 and 11) connected on a segregated network with no internet access.
I'm writing the code on a single PC (Windows 10) using Anaconda as environment and Spyder as IDE. The scripts are saved on a shared network disk that is accessible from all other PC in the segregated LAN.
And here comes my question: how should I package and distribute the code on all client PC?
My first idea was to not distribute it at all. I mean, I wanted to leave the code on the shared disk, and let the users double click on a shortcut on the desktop to have it running. The advantage is that I don't have to care about package creation and distribution.
Nevertheless I can see these limitations:
I need to install Anaconda on all PCs and, in particular on windows 7, I can only install an old release of it.
I need to modify the code in order that user-based configurations are saved on a local file and not on the shared disc.
In order to have access to shared modules between scripts, I need to add all relevant paths to the python search path on all PCs.
My second approach was to build an exe file for each script with pyinstaller and have them distributed on all clients. I can automatize the build and the copy on all pcs, so that I'm sure that everybody is using the same latest version. The advantage is that I don't need to install Anaconda everywhere but it has some drawbacks:
Each exe file is huge. All scripts have a Qt GUI and the size of the one-file exe generated by pyinstaller can easily reach 500 MB. This means that when the user double click on the icon, (s)he may have to wait a couple of seconds (depending on the disk speed and caching) before it is loaded and (s)he may thing that the computer is blocked and not working.
pyinstaller is multi-platform but not cross-platform. It means that I need to have two other development pcs, one with Win 7 and one with Win 11, to generate the exe file.
My third possibility was to generate a real python package that can be installed on all PC. And here the tricky point is, should it be installed with conda or with pip. I have a lot of confusion in mind about package building. I have seen and followed the tutorial on how to build a source and wheel python package on the python doc, but I don't know if it is the correct approach being my python environment inside anaconda.
I have seen that on git-hub you can automatically build an anaconda package starting from your python code and I would need to read the whole workflow documentation on how to do it because it doesn't look so easy to me. The drawback is that the clients PC have no access to GitHub, so I would need to manually copy the output package from a pc with internet access to somewhere on the segregated net and then let it install on all clients.
So, at the end of this long message, I hope I managed to describe my problem and I'm sure your answers will shed some light on it. I know that the question may sound trivial to the more advanced developers, but there are also newbies out here in need of good advices!
Thanks!
I've made this question because I had to go through the whole process of creating my own application using Apple's somewhat lacking documentation, and without the use of py2app. I wanted to create the whole application structure so I know exactly what was inside, as well as create an installer for it. The latter of these is still a mystery, so any additional answers with information on making a custom installer would be appreciated. As far as the actual "bundle" structure goes, however, I think I've managed to get the basics down. See the answer below.
Edit: A tutorial has been linked at the end of this answer on using PyInstaller; I don't know how much it helps as I haven't used it yet, but I have yet to figure out how to make a standalone Python application without the use of a tool like this and it may just be what you're looking for if you wish to distribute your application without relying on users knowing how to navigate their Python installations.
A generic application is really just a directory with a .app extension. So, in order to build your application, just make the folder without the extension first. You can rename it later when you're finished putting it all together. Inside this main folder will be a Contents folder, which will hold everything your application needs. Finally, inside Contents, you will place a few things:
Info.plist
MacOS
Resources
Frameworks
Here you can find some information on how to write your Info.plist file. Basically, this is where you detail information about your application.
Inside the MacOS you want to place your main executable. I'm not sure that it matters how you write it; at first, I just had a shell script that called python3 ./../Resources/MyApp.py. I didn't think this was very neat though, so eventually I called the GUI from a Python script which became my executable (I used Tkinter to build my application's GUI, and I wrote several modules which I will get to later). So now, my executable was a Python script with a shebang pointing to the Python framework in my application's Frameworks folder, and this script just created an instance of my custom Tk() subclass and ran the mainloop. Both methods worked, though, so unless someone points out a reason to choose one method over the other, feel free to pick. The one thing that I believe is necessary, is that you name your executable the SAME as your application (before adding the .app). That, I believe, is the only way that MacOS knows to use that file as your application's executable. Here is a source that describes the bundle structure in more detail; it's not a necessary read unless you really want to get into it.
In order to make your executable run smoothly, you want to make sure you know where your Python installation is. If you're like me, the first thing you tried doing on your new Mac was open up Terminal and type in python3. If this is the case, this prompted you to install the Xcode Command Line tools, which include an installation of Python 3.8.2 (most recent on Xcode 12). Then, this Python installation would be located at /usr/bin/python3, although it's actually using the Python framework located at
/Applications/Xcode.app/Developer/Library/Frameworks/Python3.framework/Versions/3.8/bin/python3
I believe, but am NOT CERTAIN, that you could simply make a copy of this framework and add it to your Frameworks folder in order to make the app portable. Make a copy of the Python3.framework folder, and add it to your app's Frameworks folder. A quick side note to be wary of; Xcode comes packaged with a lot of useful tools. In my current progress, the tool I am most hurting for is the Fortran compiler (that I believe comes as a part of GCC), which comes with Xcode. I need this to build SciPy with pip install scipy. I'm sure this is not the only package that would require tools that Xcode provides, but SciPy is a pretty popular package and I am currently facing this limitation. I think by copying the Python framework you still lose some of the symlinks that point to Xcode tools, so any additional input on this would be great.
In any case, locate the Python framework that you use to develop your programs, and copy it into the Frameworks folder.
Finally, the Resources folder. Here, place any modules that you wrote for your Python app. You also want to put your application's icon file here. Just make sure you indicate the name of the icon file, with extension, in the Info.plist file. Also, make sure that your executable knows how to access any modules you place in here. You can achieve this with
import os
os.chdir('./../Resources')
import MyModules
Finally, make sure that any dependencies your application requires are located in the Python framework site-packages. These will be located in Frameworks/Python3.framework/Versions/3.X.Y/lib/python3.x.y/site-packages/. If you call this specific installation of Python from the command line, you can use path/to/application/python3 -m pip install package and it should place the packages in the correct folder.
P.S. As far as building the installer for this application, there are a few more steps needed before your application is readily downloaded. For instance, I believe you need to use the codesign tool in order to approve your application for MacOS Gatekeeper. This requires having a developer license and manipulating certificates, which I'm not familiar with. You can still distribute the app, but anyone who downloads it will have to bypass the security features manually and it will seem a bit sketchy. If you're ready to build the installer (.pkg) file, take a look at the docs for productbuild; I used it and it works, but I don't yet know how to create custom steps and descriptions in the installer.
Additional resources:
A somewhat more detailed guide to the anatomy of a macOS app
A guide I found, but didn't use, on using codesign to get your app past Gatekeeper
A RealPython tutorial I found on using PyInstaller to build Python-based applications for all platforms
I want to create a GUI application which should work on Windows and Mac. For this I've chosen Python.
The problem is on Mac OS X.
There are 2 tools to generate an ".app" for Mac: py2app and pyinstaller.
py2app is pretty good, but it adds the source code in the package. I
don't want to share the code with the final users.
Pyinstaller generates UNIX executable, so how to run it on Mac? I
created a bundles with this executable, but the resulted ".app" is
not working.
The questions are:
How to configure py2app to include the source code in the
executable, so the final users will not have access to my program?
How to convert UNIX executable to Mac ".app" ?
Is there a way to compile Python code with GCC ?
In Windows it's easy, I created an "exe" file from Python code and
it works. Is it possible to create a single file "app" for Mac ?
P.S. I use two computers (Windows and for Mac), Python 2.7, wxPython, py2exe, py2app and pyinstaller.
Also, I have checked out these sites:
http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html
http://www.pyinstaller.org/export/develop/project/doc/Manual.html?format=raw
http://www.pyinstaller.org/wiki/Features/MacOsCompatibility
http://www.stackoverflow.com/questions/2933/an-executable-python-app
How to configure py2app to include the source code in the executable,
so the final users will not have access to my program?
Unless you very seriously hack the python interpreter (and include the mangled version) there is no really good way to hide the source from a moderately skilled and determined user. I strongly believe this is true on Windows also. Basically, whether you include true source or bytecode, a pretty clean version of the source can be recovered. More importantly, in my opinion, unless you include the actual source code (as opposed to bytecode, you will introduce a possible dependency on the interpreter version).
How to convert UNIX executable to Mac ".app" ?
What do you mean by a UNIX executable? A Darwin (OS X) binary [which isn't actually UNIX]? That can be done using the kinds of tools you already mentioned, but it must be done carefully to avoid library dependencies.
If all you want it a simple wrapper to put a command-line binary into a window, it's pretty easy to accomplish and the free XCode suite has several examples that would serve (depending on what output
you wan to deliver, if any).
Is there a way to compile Python code with GCC ?
GCC does not compile Python. It's a different language (although there tools in the gcc family rthat support multiple language front-ends, but not Python). There are tools that attempt to translate Python into C, and then you can compile that into a true binary, but this only works for programs that avoid certain types of construct, and the process (and restrictions) need to apply your libraries as well.
One project to allow this is Cython. It works well for some types
of code, mostly numerical code, but it is not trivial to install and
exploit, very especially if you want to produce something that runs on multiple
different computers.
In Windows it's easy, I created an "exe" file from Python code and it
works. Is it possible to create a single file "app" for Mac ?
I would have to say I am skeptical -- very skeptical -- about this. Just like the OS X case, the exe almost certainly has the source code trivially accessible within it.
One fairly easy trick is to encrypt the source code and then decrypt it on the fly, but this
seems to me like more trouble than it's worth.
PyInstaller will automatically create bundles under Mac OSX for windowed executables. When running ypinstaller.py, make sure to pass the option "--windowed".
This feature is documented in the website of pyinstaller
If you're not completely committed to wxPython (and for anyone else looking for a cross platform Python GUI framework), I recommend you check out Kivy. It's cross platform, GPU accelerated, and it will do the app packaging for you. It's easy to jump into, has a well thought-out architecture, and gives you an incredible amount of flexibility in terms of the interface. It's the best way I've found to make a cross platform Python GUI app.
cxFreeze was the choice.
I use it pack my python program to a Mac OS X app. Which works like a charm.
Automator was already mentioned as a quick and simple solution for Pythons scripts that are contained in a single file, but since the Automator UI has so many options, and it is not obvious how to actually do it, I'll provide step-by-step instructions (verified to work on Yosemite):
In Automator select File > New and pick Application as document type.
Next, make sure Actions tab is selected on the left, and then in the search box type run. Among other options you'll see Run Shell Script — doubleclick it, and an editor window will appear in the right panel.
From the Shell dropdown menu select /usr/bin/python.
Paste your Python code into the edit window and then pick File > Save.
By default, the app will be saved under $HOME/Applications and will appear in Spotlight.
If you want to be able to set your own icon and have some fancy features, like task bar icons with a menu, log windows etc, then have a look at Platypus — an open-source app for creating MacOS native bundles.
2: You can't "convert" it, but you can move the executable to App.app/Contents/MacOS/something in a .app file, with CFBundleExecutable set to "something". This would not generally be recommended.
A motivated person could probably reconstruct usable source code from the Python bytecode in your app, so you might reconsider your opposition to py2app. If you don't trust your final users, why are you doing business with them?
Having used py2exe for windows users so they wouldn't have to deal with library versions, I've torn apart the compiled programs, they include the python bytecode files. While you can make it a violation of the license to look inside those, the fact is that if a computer can execute them, I can read them. It is possible to compile python programs with gcc, via a C preprocessor (try looking for 2c.py on google), I don't know if any of them support GCC. Again, you don't gain any security through using them, but you can get a significant speed improvement.
I haven't tried it with big Python projects, but for my own scripts, the easiest way I found was to use Automator
You can interactively create an app project with Run Shell Script action, then paste in your script in its editor, select your shell program (/usr/bin/python), finally save the project. And you have yourself a Mac native app.
Automator can also be driven by AppleScript. So you can pipeline this py-2-app conversion process to your build scripts.
I've never tested a GUI program with it so I don't know if you'll be happy with it. But I'd give it a try since you may wonder how well all the cited 3rd-party python modules/applications are maintained, and how long they are gonna last. Coming bundled with OS X, Automator will likely stay, unless Apple got REALLY tired of it.
cxFreeze is best solution available, first create your program or application using python and than make setup file for your application, and than build the app using build command python setup.py build, according to your requirement you need to make some changes.
The only way is py2app. You have no other way. Sorry.
The research you did seems very solid and you did not miss anything.
My company is working on an application that is half Qt/C++ for the editor interface and half Django (via QtWebKit browser control) for the runtime. What we want to do is distribute a minimal python installation with our application.
For instance, our Mac app bundle would ideally be structured something like this:
TheApp.app/
Contents/
MacOS/
TheApp
Resources/
MinimalPythonInstallation/
On Windows:
C:\Program Files\TheApp\
TheApp.exe
MinimalPythonInstallation\
I've seen plenty of projects out there for distributing full Python applications such as py2app, py2exe, and PyInstaller. Those seem to have some of the features I'm looking for, but without the ability to just make a minimal python distribution. i.e. the python executable, Django, and the bare minimum of the python standard library needed by Django, our python code, etc.
Is there anything out there that can do what I'm looking for?
You can find the set of modules you need with modulefinder -- indeed, I believe that's a key part of what the systems you mention, like py2exe and PyInstaller, do for you, so I'm not clear why you want to "reinvent the wheel" -- care to clarify? Have you looked at exactly what e.g. PyInstaller puts in the executables it generates, and, if so, why isn't that good enough for you? If you explain this in detail, maybe there's some extra way we can help.
(PyInstaller is cross-platform, so, if you want to support Mac as well as Windows, it's probably the one you'll want, since py2exe is Windows-only).
I wrote a Python program. I would like to add to it an installation script that will set up everything necessary - like desktop icon, entry in the menu, home directory file, etc.
I'm working on Linux (ubuntu). When a Python program is installed, what needs to happen in general? I know that it probably depends on the nature of the program.
Can you give me some general ideas? Or, point me in the right direction? I have no idea how to look for this on Google.
Thanks
If it's a Python program you're trying to package, you should consider using its 'standard' distribution framework distutils. I can't replicate the entire document here but I'd recommend that you read it. Once you're done with that, check out the Hitchhikers guide to packaging which contains details on distribute - the extensions to distutils that allow you to package and distribute more effectively.
You could create an rpm easily using checkinstall. Search for checkinstall in google and download it. It will allow you to create an rpm and set the options.
For Ubuntu if you want it to be easily distributable to other Ubuntu users it'll have to be packaged properly, which is no simple task. You might want to consult their Packaging Guide for more information.
Otherwise, generally speaking there are a few standard packaging options for Python. Setuptools is popular, but becoming reviled lately. Read James Bennett's blog post "On Packaging" for a decent in-depth look into the ups and downs of the Python packaging world.
How a program is launched and placed in the menu is determined by a .desktop file (you can read the specification or just look at some examples from /usr/share/applications). Properly installing a program (placing all files in the right directories and so on) requires either making a package like a deb or rpm, or you could use something like distutils or setuptools.
It may also help to just look at some (open source) examples of Python programs for Linux.