takluyver / pynsist

Build Windows installers for Python applications
https://pynsist.readthedocs.io/
Other
896 stars 119 forks source link

Specify Python installation path and update environmental variable PATH #134

Closed adendek closed 6 years ago

adendek commented 6 years ago

I am developing some pseudo-GUI application (based on thinker) and I need to create executable Windows Installer. I created the main function which creates the logger and the input widget.

import logging
import sys
import os
import datetime

import InputWidget

logger = logging.getLogger("xxx")

def main():
    filename = "xxx" + datetime.datetime.now().strftime('%Y-%m-%d-%H.%M.%S') + ".log"

    log_file = os.path.abspath(os.path.join('logs',filename))

    logging.basicConfig(filename=log_file,
                        filemode='a',
                        format='%(asctime)s:%(msecs)d %(levelname)s %(name)s \t %(message)s',
                        datefmt='%H:%M:%S',
                        level=logging.DEBUG)

    logger.info("Start application")

    widget = InputWidget.InputWidget()
    widget.run()

Then I created installer.cfg file following this example

[Application]
name=xxx
version=1.0
entry_point=main:main
icon=config/Stopwatch.ico
console=true

[Python]
version=2.7.14
bitness=64

[Include]
# Importable packages that your application requires, one per line
packages = src
    future
    gspread
    impala
    mistune
    numpy
    oauth2client
    pandas

pypi_wheels = google-api-python-client==1.6.4
    PyDrive==1.3.1
    Pygments==2.2.0
    pygsheets==1.1.3

# Other files and folders that should be installed
files = config\
    logs\

But after installation, the windows is not able to find the python ("'python' is not recognized as an internal or external command, operable program or batch file.") How can I specify the python installation point?
Can you tell how can I export the environmental variables (PATH)? How can I improve my installer.cfg file?

takluyver commented 6 years ago

Hello again, this looks familiar. ;-)

When you get that error message, how are you trying to launch it? From the start menu shortcut, by double clicking something in the install directory, or using a command prompt? If you're using the shortcut, what does Windows think its target is? If you're double clicking something, what's inside that file?

It shouldn't be necessary to tell it where Python is (and so there isn't a good way to do that) - the installer is meant to install Python and set your application up to use it automatically. But it seems that has gone wrong one way or another.

adendek commented 6 years ago

When I trying to run the App using double click on the icon I am not able to capture the error message. The console is destroyed immediately. When I am running the application using the command lines the message "python is not recognizable as ..." appears.

The point is to create the app for nontechnical users. It needs to be as easy as possible. Just like an ordinary Windows application. I can't force them to manually install python and run it from the command line. It is too hard. So that why I am looking for some tool to create executable python installer.

Siecje commented 6 years ago

It should just work without having to install Python or run it from the command line.

To help diagnose what the problem is can you right click on the shortcut and then select Properties to see what the shortcut target is and paste it here?

takluyver commented 6 years ago

I 100% agree on the point. That's what Pynsist is meant to do. It's just not working right, so we need to figure out why.

The thing I'm not sure about is whether the error message that disappears immediately when you double-click is the same as the one you see running in the command prompt. You could try building with console=false - if it gets as far as running Python, it should then write the error to a file so you can inspect it. But if it's failing to even start Python, you probably won't get any information at all.

takluyver commented 6 years ago

BTW if it's practical to run your code with Python 3, then you can put format=bundled in the [Python] section. That installs Python a different way, which is less prone to problems like this. I'm not trying to tell you how to write your application, but this relies on things which are only available for Python 3.5 and above.

adendek commented 6 years ago

I moved my project to Python3 and now I am able to create the executable installer (when I commented out all packages and 99% of the code) . But the new problems come. There is some issue with regard to package importing,

  File "C:\Users\dead7002\AppData\Roaming\Python\Python27\site-packages\nsist\pypi.py", line 109, in fetch
    raise NoWheelError('No compatible wheels found for {0.name} {0.version}'.format(self))
nsist.pypi.NoWheelError: No compatible wheels found for httplib2 0.10.3
takluyver commented 6 years ago

httplib2 doesn't currently publish wheels. For now, the pypi_wheels option only works for projects that have wheels on PyPI. For projects that don't, you'll need to list them under packages instead - that copies the installed files from your computer.

takluyver commented 6 years ago

(Alternatively, you can run pip wheel httplib2 to build a wheel yourself, and then use extra_wheel_sources to point Pynsist to the directory containing it. Docs: http://pynsist.readthedocs.io/en/latest/cfgfile.html#include-section )

adendek commented 6 years ago

Thank you for all of your comments and suggestions. But your tool is too complicated for my purpose. I had a lot of issues regarding packages import. In many cases, the program terminates via an uncaught exception. So I decided to move to cx_Freeze.
Your solution is more elegant. The software creates installation wizard and you can specify the installation point but from my perspective, the executable binary is a better and easier to distribute.

Siecje commented 6 years ago

@adendek In case this might help you. I have a script to take the cx_Freeze output and create a Windows MSI installer using Wix Toolset.

Repo: https://github.com/Siecje/qml-testing/tree/cxfreeze Script: https://github.com/Siecje/qml-testing/blob/cxfreeze/build_msi.py Wix Code: https://github.com/Siecje/qml-testing/tree/cxfreeze/wix

takluyver commented 6 years ago

@adendek OK, that's fair enough. If you try Pynsist again, uncaught exceptions should be written to a log file to help in debugging them. I actually wrote Pynsist because I was frustrated with the difficulties of using cx_Freeze. It is an improvement in some ways, but reliably packaging an application is a tricky problem to solve. If cx_Freeze works for you, that's great.

@Siecje Oh cool, I didn't know you were playing with Wix. I was just experimenting with it the other day. Here are the files I created for it - it looks like I wound up with something quite similar to your code, using heat to gather a list of files. Unfortunately when I installed the result in a VM, PyQt5 threw an error about a missing DLL.