Successfully builds a .exe with Python3/Qt5. Switched from pyinstaller to py2exe. (#261)

This commit is contained in:
Micah Lee 2016-02-15 22:16:09 -08:00
parent d1c36fa04f
commit d438e25b9b
6 changed files with 91 additions and 173 deletions

View File

@ -104,7 +104,7 @@ These instructions include adding folders to the path in Windows. To do this, go
First, download and install the 32-bit (x86) version of Python 3.4.x from https://www.python.org/downloads/windows/. You need 3.4 instead of 3.5 because PyQt5 was built with 3.4. Add `C:\Python34` and `C:\Python34\Scripts` to the path.
Open a command prompt and install some dependencies with pip: `pip install flask stem pyinstaller`
Open a command prompt and install some dependencies with pip: `pip install flask stem py2exe`
Download and install Qt5 from https://www.qt.io/download-open-source/. I downloaded `qt-unified-windows-x86-2.0.2-2-online.exe`. There's no need to login to a Qt account during installation. Make sure you install the latest Qt 5.x.
@ -133,12 +133,12 @@ If you want to sign binaries with Authenticode:
### To make a .exe:
* Open a command prompt, cd into the onionshare directory, and type: `pyinstaller -y install\onionshare-win.spec`. Inside the `dist` folder there will be a folder called `onionshare` with `onionshare.exe` in it.
* Open a command prompt, cd into the onionshare directory, and type: `python setup.py py2exe`. `onionshare.exe` and all of its supporting files will get created inside the `dist` folder.
### To build the installer:
Note that you must have a codesigning certificate installed in order to use the `install\build_exe.bat` script, because it codesigns `onionshare.exe`, `uninstall.exe`, and `OnionShare_Setup.exe`.
s
Open a command prompt, cd to the onionshare directory, and type: `install\build_exe.bat`
This will prompt you to codesign three binaries and execute one unsigned binary. When you're done clicking through everything you will have `dist\OnionShare_Setup.exe`.

View File

@ -1,8 +1,8 @@
REM use pyinstaller to builder a folder with onionshare.exe
pyinstaller -y install\onionshare-win.spec
REM use py2exe to builder a folder with onionshare.exe
python setup.py py2exe
REM sign onionshare.exe
signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\onionshare\onionshare.exe
signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\onionshare.exe
REM build an installer, dist\OnionShare_Setup.exe
makensis.exe install\onionshare.nsi

View File

@ -1,46 +0,0 @@
# -*- mode: python -*-
a = Analysis(['onionshare-launcher.py'],
#hiddenimports=['onionshare', 'onionshare_gui'],
#excludes=['_tkinter'],
hookspath=None,
runtime_hooks=None)
a.datas += [
('images/logo.png', 'images/logo.png', 'DATA'),
('images/drop_files.png', 'images/drop_files.png', 'DATA'),
('images/server_stopped.png', 'images/server_stopped.png', 'DATA'),
('images/server_started.png', 'images/server_started.png', 'DATA'),
('images/server_working.png', 'images/server_working.png', 'DATA'),
('locale/de.json', 'locale/de.json', 'DATA'),
('locale/en.json', 'locale/en.json', 'DATA'),
('locale/eo.json', 'locale/eo.json', 'DATA'),
('locale/es.json', 'locale/es.json', 'DATA'),
('locale/fi.json', 'locale/fi.json', 'DATA'),
('locale/fr.json', 'locale/fr.json', 'DATA'),
('locale/it.json', 'locale/it.json', 'DATA'),
('locale/nl.json', 'locale/nl.json', 'DATA'),
('locale/no.json', 'locale/no.json', 'DATA'),
('locale/pt.json', 'locale/pt.json', 'DATA'),
('locale/ru.json', 'locale/ru.json', 'DATA'),
('locale/tr.json', 'locale/tr.json', 'DATA'),
('version', 'version', 'DATA'),
]
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='onionshare.exe',
debug=False,
strip=False,
upx=True,
icon='install/onionshare.ico',
console=False)
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
Tree('onionshare', prefix='onionshare'),
Tree('onionshare_gui', prefix='onionshare_gui'),
[('LICENSE', 'LICENSE', 'DATA')],
strip=False,
upx=True,
name='onionshare')

View File

@ -1,9 +1,9 @@
!define APPNAME "OnionShare"
!define BINPATH "..\dist\onionshare"
!define BINPATH "..\dist"
!define ABOUTURL "https:\\onionshare.org\"
# change these with each release
!define INSTALLSIZE 31616
!define INSTALLSIZE 60104
!define VERSIONMAJOR 0
!define VERSIONMINOR 8
!define VERSIONSTRING "0.8.1"
@ -61,27 +61,13 @@ FunctionEnd
Section "install"
# application
SetOutPath "$INSTDIR"
File "onionshare.ico"
File "${BINPATH}\onionshare.exe"
File "${BINPATH}\license"
SetOutPath "$INSTDIR\onionshare"
File "${BINPATH}\onionshare\__init__.py"
File "${BINPATH}\onionshare\404.html"
File "${BINPATH}\onionshare\helpers.py"
File "${BINPATH}\onionshare\hs.py"
File "${BINPATH}\onionshare\index.html"
File "${BINPATH}\onionshare\onionshare.py"
File "${BINPATH}\onionshare\socks.py"
File "${BINPATH}\onionshare\strings.py"
File "${BINPATH}\onionshare\web.py"
SetOutPath "$INSTDIR\onionshare_gui"
File "${BINPATH}\onionshare_gui\__init__.py"
File "${BINPATH}\onionshare_gui\common.py"
File "${BINPATH}\onionshare_gui\downloads.py"
File "${BINPATH}\onionshare_gui\file_selection.py"
File "${BINPATH}\onionshare_gui\onionshare_gui.py"
File "${BINPATH}\onionshare_gui\options.py"
File "${BINPATH}\onionshare_gui\server_status.py"
File "${BINPATH}\license.txt"
File "${BINPATH}\version"
File "${BINPATH}\onionshare.ico"
SetOutPath "$INSTDIR\html"
File "${BINPATH}\html\404.html"
File "${BINPATH}\html\index.html"
SetOutPath "$INSTDIR\images"
File "${BINPATH}\images\logo.png"
File "${BINPATH}\images\drop_files.png"
@ -103,54 +89,35 @@ Section "install"
File "${BINPATH}\locale\tr.json"
# dependencies
SetOutPath "$INSTDIR\platforms"
File "${BINPATH}\platforms\qwindows.dll"
SetOutPath $INSTDIR
File "${BINPATH}\_bz2.pyd"
File "${BINPATH}\_ctypes.pyd"
File "${BINPATH}\_decimal.pyd"
File "${BINPATH}\_hashlib.pyd"
File "${BINPATH}\_lzma.pyd"
File "${BINPATH}\_multiprocessing.pyd"
File "${BINPATH}\_socket.pyd"
File "${BINPATH}\_ssl.pyd"
File "${BINPATH}\bz2.pyd"
File "${BINPATH}\microsoft.vc90.crt.manifest"
File "${BINPATH}\msvcm90.dll"
File "${BINPATH}\msvcp90.dll"
File "${BINPATH}\msvcr90.dll"
File "${BINPATH}\onionshare.exe.manifest"
File "${BINPATH}\icudt53.dll"
File "${BINPATH}\icuin53.dll"
File "${BINPATH}\icuuc53.dll"
File "${BINPATH}\library.zip"
File "${BINPATH}\license.txt"
File "${BINPATH}\pyexpat.pyd"
File "${BINPATH}\PyQt4.QtCore.pyd"
File "${BINPATH}\PyQt4.QtGui.pyd"
File "${BINPATH}\python27.dll"
File "${BINPATH}\pywintypes27.dll"
File "${BINPATH}\qtcore4.dll"
File "${BINPATH}\qtgui4.dll"
File "${BINPATH}\qtopengl4.dll"
File "${BINPATH}\qtsvg4.dll"
File "${BINPATH}\qtxml4.dll"
File "${BINPATH}\PyQt5.QtCore.pyd"
File "${BINPATH}\PyQt5.QtGui.pyd"
File "${BINPATH}\PyQt5.QtWidgets.pyd"
File "${BINPATH}\python34.dll"
File "${BINPATH}\pywintypes34.dll"
File "${BINPATH}\Qt5Core.dll"
File "${BINPATH}\Qt5Gui.dll"
File "${BINPATH}\Qt5Widgets.dll"
File "${BINPATH}\select.pyd"
File "${BINPATH}\sip.pyd"
File "${BINPATH}\unicodedata.pyd"
File "${BINPATH}\win32api.pyd"
File "${BINPATH}\win32pipe.pyd"
File "${BINPATH}\win32wnet.pyd"
SetOutPath "$INSTDIR\qt4_plugins\accessible"
File "${BINPATH}\qt4_plugins\accessible\qtaccessiblewidgets4.dll"
SetOutPath "$INSTDIR\qt4_plugins\codecs"
File "${BINPATH}\qt4_plugins\codecs\qcncodecs4.dll"
File "${BINPATH}\qt4_plugins\codecs\qjpcodecs4.dll"
File "${BINPATH}\qt4_plugins\codecs\qkrcodecs4.dll"
File "${BINPATH}\qt4_plugins\codecs\qtwcodecs4.dll"
SetOutPath "$INSTDIR\qt4_plugins\graphicssystems"
File "${BINPATH}\qt4_plugins\graphicssystems\qglgraphicssystem4.dll"
SetOutPath "$INSTDIR\qt4_plugins\iconengines"
File "${BINPATH}\qt4_plugins\iconengines\qsvgicon4.dll"
SetOutPath "$INSTDIR\qt4_plugins\imageformats"
File "${BINPATH}\qt4_plugins\imageformats\qgif4.dll"
File "${BINPATH}\qt4_plugins\imageformats\qico4.dll"
File "${BINPATH}\qt4_plugins\imageformats\qjpeg4.dll"
File "${BINPATH}\qt4_plugins\imageformats\qmng4.dll"
File "${BINPATH}\qt4_plugins\imageformats\qsvg4.dll"
File "${BINPATH}\qt4_plugins\imageformats\qtga4.dll"
File "${BINPATH}\qt4_plugins\imageformats\qtiff4.dll"
SetOutPath "$INSTDIR\include"
File "${BINPATH}\Include\pyconfig.h"
# uninstaller
!ifndef INNER
@ -195,25 +162,11 @@ FunctionEnd
# remove files
Delete "$INSTDIR\onionshare.exe"
Delete "$INSTDIR\LICENSE"
Delete "$INSTDIR\license.txt"
Delete "$INSTDIR\version"
Delete "$INSTDIR\onionshare.ico"
Delete "$INSTDIR\uninstall.exe"
Delete "$INSTDIR\onionshare\__init__.py"
Delete "$INSTDIR\onionshare\404.html"
Delete "$INSTDIR\onionshare\helpers.py"
Delete "$INSTDIR\onionshare\hs.py"
Delete "$INSTDIR\onionshare\index.html"
Delete "$INSTDIR\onionshare\onionshare.py"
Delete "$INSTDIR\onionshare\socks.py"
Delete "$INSTDIR\onionshare\strings.py"
Delete "$INSTDIR\onionshare\web.py"
Delete "$INSTDIR\onionshare_gui\__init__.py"
Delete "$INSTDIR\onionshare_gui\common.py"
Delete "$INSTDIR\onionshare_gui\downloads.py"
Delete "$INSTDIR\onionshare_gui\file_selection.py"
Delete "$INSTDIR\onionshare_gui\onionshare_gui.py"
Delete "$INSTDIR\onionshare_gui\options.py"
Delete "$INSTDIR\onionshare_gui\server_status.py"
Delete "$INSTDIR\html\404.html"
Delete "$INSTDIR\html\index.html"
Delete "$INSTDIR\images\logo.png"
Delete "$INSTDIR\images\drop_files.png"
Delete "$INSTDIR\images\server_stopped.png"
@ -231,60 +184,38 @@ FunctionEnd
Delete "$INSTDIR\locale\pt.json"
Delete "$INSTDIR\locale\ru.json"
Delete "$INSTDIR\locale\tr.json"
Delete "$INSTDIR\qt4_plugins\accessible\qtaccessiblewidgets4.dll"
Delete "$INSTDIR\qt4_plugins\graphicssystems\qglgraphicssystem4.dll"
Delete "$INSTDIR\qt4_plugins\iconengines\qsvgicon4.dll"
Delete "$INSTDIR\qt4_plugins\codecs\qjpcodecs4.dll"
Delete "$INSTDIR\qt4_plugins\codecs\qkrcodecs4.dll"
Delete "$INSTDIR\qt4_plugins\codecs\qtwcodecs4.dll"
Delete "$INSTDIR\qt4_plugins\codecs\qcncodecs4.dll"
Delete "$INSTDIR\qt4_plugins\imageformats\qmng4.dll"
Delete "$INSTDIR\qt4_plugins\imageformats\qico4.dll"
Delete "$INSTDIR\qt4_plugins\imageformats\qgif4.dll"
Delete "$INSTDIR\qt4_plugins\imageformats\qjpeg4.dll"
Delete "$INSTDIR\qt4_plugins\imageformats\qsvg4.dll"
Delete "$INSTDIR\qt4_plugins\imageformats\qtga4.dll"
Delete "$INSTDIR\qt4_plugins\imageformats\qtiff4.dll"
Delete "$INSTDIR\Include\pyconfig.h"
Delete "$INSTDIR\platforms\qwindows.dll"
Delete "$INSTDIR\_bz2.pyd"
Delete "$INSTDIR\_ctypes.pyd"
Delete "$INSTDIR\_decimal.pyd"
Delete "$INSTDIR\_hashlib.pyd"
Delete "$INSTDIR\_lzma.pyd"
Delete "$INSTDIR\_multiprocessing.pyd"
Delete "$INSTDIR\_socket.pyd"
Delete "$INSTDIR\_ssl.pyd"
Delete "$INSTDIR\bz2.pyd"
Delete "$INSTDIR\Microsoft.VC90.CRT.manifest"
Delete "$INSTDIR\msvcm90.dll"
Delete "$INSTDIR\msvcp90.dll"
Delete "$INSTDIR\msvcr90.dll"
Delete "$INSTDIR\onionshare.exe.manifest"
Delete "$INSTDIR\icudt53.dll"
Delete "$INSTDIR\icuin53.dll"
Delete "$INSTDIR\icuuc53.dll"
Delete "$INSTDIR\library.zip"
Delete "$INSTDIR\license.txt"
Delete "$INSTDIR\pyexpat.pyd"
Delete "$INSTDIR\PyQt4.QtCore.pyd"
Delete "$INSTDIR\PyQt4.QtGui.pyd"
Delete "$INSTDIR\python27.dll"
Delete "$INSTDIR\pywintypes27.dll"
Delete "$INSTDIR\QtCore4.dll"
Delete "$INSTDIR\QtGui4.dll"
Delete "$INSTDIR\QtOpenGL4.dll"
Delete "$INSTDIR\QtSvg4.dll"
Delete "$INSTDIR\QtXml4.dll"
Delete "$INSTDIR\PyQt5.QtCore.pyd"
Delete "$INSTDIR\PyQt5.QtGui.pyd"
Delete "$INSTDIR\PyQt5.QtWidgets.pyd"
Delete "$INSTDIR\python34.dll"
Delete "$INSTDIR\pywintypes34.dll"
Delete "$INSTDIR\Qt5Core.dll"
Delete "$INSTDIR\Qt5Gui.dll"
Delete "$INSTDIR\Qt5Widgets.dll"
Delete "$INSTDIR\select.pyd"
Delete "$INSTDIR\sip.pyd"
Delete "$INSTDIR\unicodedata.pyd"
Delete "$INSTDIR\win32api.pyd"
Delete "$INSTDIR\win32pipe.pyd"
Delete "$INSTDIR\win32wnet.pyd"
rmDir "$INSTDIR\onionshare"
rmDir "$INSTDIR\onionshare_gui"
rmDir "$INSTDIR\html"
rmDir "$INSTDIR\images"
rmDir "$INSTDIR\locale"
rmDir "$INSTDIR\Include"
rmDir "$INSTDIR\qt4_plugins\accessible"
rmDir "$INSTDIR\qt4_plugins\bearer"
rmDir "$INSTDIR\qt4_plugins\codecs"
rmDir "$INSTDIR\qt4_plugins\graphicssystems"
rmDir "$INSTDIR\qt4_plugins\iconengines"
rmDir "$INSTDIR\qt4_plugins\imageformats"
rmDir "$INSTDIR\qt4_plugins"
rmDir "$INSTDIR\platforms"
rmDir "$INSTDIR"
# remove uninstaller information from the registry

View File

@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from __future__ import division
import os, sys, subprocess, time, hashlib, platform, json, locale, socket
import os, subprocess, time, hashlib, platform, json, locale, socket
import argparse, queue, inspect, base64, random, functools, logging, ctypes
import hmac, shutil
import stem, stem.control, flask
@ -26,4 +26,12 @@ from PyQt5 import QtCore, QtWidgets, QtGui
import onionshare, onionshare_gui
# Disable py2exe logging in Windows. Comment these if you need logs. See:
# http://www.py2exe.org/index.cgi/StderrLog
# http://stackoverflow.com/questions/20549843/py2exe-generate-log-file
import sys
f = open(os.devnull, 'w')
sys.stdout = f
sys.stderr = f
onionshare_gui.main()

View File

@ -121,3 +121,28 @@ elif system == 'Darwin':
},
setup_requires=['py2app', 'flask', 'stem'],
)
elif system == 'Windows':
import py2exe
setup(
name='OnionShare',
version=version,
description=description,
long_description=long_description,
data_files=[
('images', images),
('locale', locale),
('html', ['onionshare/index.html', 'onionshare/404.html']),
('', ['version', 'install/license.txt', 'install/onionshare.ico']),
('platforms', ['C:\\Python34\\Lib\\site-packages\\PyQt5\\plugins\\platforms\\qwindows.dll'])
],
windows=['install/windows_scripts/onionshare.py'],
options={
'py2exe': {
'includes': [
'PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets',
'jinja2', 'jinja2.ext', 'sip']
}
},
setup_requires=['py2exe', 'flask', 'stem'],
)