Add a windows setup builder (#981)
* Add a package builder for windows install * Remove old win installer build * Update setup instructions * Some minor clarifications to docs and README
This commit is contained in:
committed by
GitHub
parent
71419eeda3
commit
a0cdf44deb
@@ -45,10 +45,15 @@ You can also use the novelWriter [PPA](https://launchpad.net/~vkbo/+archive/ubun
|
||||
For more details, check the [Linux](https://novelwriter.readthedocs.io/en/latest/setup_linux.html)
|
||||
setup chapter in the documentation.
|
||||
|
||||
### Other Operating Systems
|
||||
### Windows 10+
|
||||
|
||||
For a regular installation, it is recommended that you download one of the minimal zip files from
|
||||
the [Releases](https://github.com/vkbo/novelWriter/releases) page or the
|
||||
The Release page has a `setup.exe` file for Windows 10, that should also work on other Windows
|
||||
versions. The installer includes Python 3.10 and the library dependencies.
|
||||
|
||||
### Other Install Options
|
||||
|
||||
You can also download and install one of the minimal zip files from the
|
||||
[Releases](https://github.com/vkbo/novelWriter/releases) page or the
|
||||
[novelwriter.io](https://novelwriter.io/) website.
|
||||
The [documentation](https://novelwriter.readthedocs.io/) has detailed install instructions for
|
||||
[Linux](https://novelwriter.readthedocs.io/en/latest/setup_linux.html),
|
||||
|
||||
@@ -6,17 +6,25 @@ Setup on Windows
|
||||
|
||||
This is a brief guide to how you can get novelWriter running on a Windows computer.
|
||||
|
||||
Unlike other operating systems, Windows does not come prepared with an environment to run Python
|
||||
applications, so you must first install Python. After that, running novelWriter is straightforward.
|
||||
|
||||
|
||||
.. _a_setup_win_install:
|
||||
|
||||
Install novelWriter
|
||||
===================
|
||||
Standard Installer
|
||||
==================
|
||||
|
||||
The recommended way to run novelWriter on Windows is to download the "Minimal Package" option from
|
||||
the `main website`_, or from the GitHub_ releases page (it's the same download file).
|
||||
You can install novelWriter with dependencies embedded using the Windows Installer (setup.exe) file
|
||||
from the `main website`_, or from the GitHub_ releases page. Installing it should be
|
||||
straightforward.
|
||||
|
||||
If you have any issues, try uninstalling the previous version and making a fresh install.
|
||||
|
||||
|
||||
.. _a_setup_win_minimal:
|
||||
|
||||
Minimal Package
|
||||
===============
|
||||
|
||||
Alternatively, you can run novelWriter from the "Minimal Package" option from the `main website`_,
|
||||
or from the GitHub_ releases page (it's the same download file).
|
||||
|
||||
This is a zip file containing only the files you need to run novelWriter on Windows. In order to
|
||||
make it run on your system, you must first have Python installed (Step 1). Thereafter, a script
|
||||
@@ -119,14 +127,3 @@ The above steps can be reverted by running:
|
||||
pip uninstall -r requirements.txt
|
||||
|
||||
.. _Python Package Index: https://pypi.org/
|
||||
|
||||
|
||||
Windows Installer
|
||||
-----------------
|
||||
|
||||
There used to be a Windows installer, but this is no longer provided. See the `installer issue`_
|
||||
for more info on why. You can still create the installer yourself if you want to. It can be
|
||||
generated with the provided ``setup.py`` script. use the script's ``help`` command to get further
|
||||
instructions.
|
||||
|
||||
.. _installer issue: https://github.com/vkbo/novelWriter/issues/640
|
||||
|
||||
@@ -837,16 +837,34 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
|
||||
|
||||
|
||||
##
|
||||
# Make Simple Package (build-pyz)
|
||||
# Make Windows Setup EXE (build-win-exe)
|
||||
##
|
||||
|
||||
def makeSimplePackage(embedPython):
|
||||
"""Run zipapp to freeze the packages. This assumes zipapp and pip
|
||||
are already installed.
|
||||
def makeWindowsEmbedded(sysArgs):
|
||||
"""Set up a package with embedded Python and dependencies for
|
||||
Windows installation.
|
||||
"""
|
||||
import urllib.request
|
||||
import zipfile
|
||||
import zipapp
|
||||
import compileall
|
||||
|
||||
print("")
|
||||
print("Build Standalone Windows Package")
|
||||
print("================================")
|
||||
print("")
|
||||
|
||||
minimalZip = None
|
||||
packVersion = "none"
|
||||
if len(sysArgs) >= 2:
|
||||
if os.path.isfile(sysArgs[1]):
|
||||
minimalZip = sysArgs[1]
|
||||
|
||||
if minimalZip is None:
|
||||
print("Please provide the path to the minimal win pacage as an argument")
|
||||
sys.exit(1)
|
||||
|
||||
packVersion = os.path.basename(minimalZip).split("-")[1]
|
||||
print("Version: %s" % packVersion)
|
||||
|
||||
# Set Up Folder
|
||||
# =============
|
||||
@@ -855,100 +873,66 @@ def makeSimplePackage(embedPython):
|
||||
os.mkdir("dist")
|
||||
|
||||
outDir = os.path.join("dist", "novelWriter")
|
||||
zipDir = os.path.join("dist", "zipapp_temp")
|
||||
libDir = os.path.join(outDir, "lib")
|
||||
if os.path.isdir(zipDir):
|
||||
shutil.rmtree(zipDir)
|
||||
if os.path.isdir(outDir):
|
||||
shutil.rmtree(outDir)
|
||||
|
||||
os.mkdir(outDir)
|
||||
os.mkdir(libDir)
|
||||
|
||||
# Extract Source Files
|
||||
# ====================
|
||||
|
||||
print("Extracting source files ...")
|
||||
with zipfile.ZipFile(minimalZip, "r") as inFile:
|
||||
inFile.extractall(outDir)
|
||||
|
||||
shutil.copyfile(
|
||||
os.path.join(outDir, "novelwriter", "assets", "icons", "novelwriter.ico"),
|
||||
os.path.join(outDir, "novelwriter.ico")
|
||||
)
|
||||
|
||||
compileall.compile_dir(os.path.join(outDir, "novelwriter"))
|
||||
|
||||
print("Done")
|
||||
print("")
|
||||
|
||||
# Download Python Embeddable
|
||||
# ==========================
|
||||
|
||||
if embedPython:
|
||||
print("")
|
||||
print("# Adding Python Embeddable")
|
||||
print("# ========================")
|
||||
print("")
|
||||
print("Adding Python embeddable ...")
|
||||
|
||||
pyVers = "%d.%d.%d" % (sys.version_info[:3])
|
||||
zipFile = "python-%s-embed-amd64.zip" % pyVers
|
||||
pyZip = os.path.join("dist", zipFile)
|
||||
if not os.path.isfile(pyZip):
|
||||
pyUrl = f"https://www.python.org/ftp/python/{pyVers}/{zipFile}"
|
||||
print("Downloading: %s" % pyUrl)
|
||||
urllib.request.urlretrieve(pyUrl, pyZip)
|
||||
pyVers = "%d.%d.%d" % (sys.version_info[:3])
|
||||
zipFile = "python-%s-embed-amd64.zip" % pyVers
|
||||
pyZip = os.path.join("dist", zipFile)
|
||||
if not os.path.isfile(pyZip):
|
||||
pyUrl = f"https://www.python.org/ftp/python/{pyVers}/{zipFile}"
|
||||
print("Downloading: %s" % pyUrl)
|
||||
urllib.request.urlretrieve(pyUrl, pyZip)
|
||||
|
||||
print("Extracting ...")
|
||||
with zipfile.ZipFile(pyZip, "r") as inFile:
|
||||
inFile.extractall(outDir)
|
||||
print("Extracting ...")
|
||||
with zipfile.ZipFile(pyZip, "r") as inFile:
|
||||
inFile.extractall(outDir)
|
||||
|
||||
print("Done")
|
||||
print("")
|
||||
|
||||
# Build Additional Assets
|
||||
# =======================
|
||||
|
||||
buildQtI18n()
|
||||
buildSampleZip()
|
||||
buildPdfManual()
|
||||
|
||||
# Copy Package Files
|
||||
# ==================
|
||||
|
||||
print("")
|
||||
print("# Copying Package Files")
|
||||
print("# =====================")
|
||||
print("Done")
|
||||
print("")
|
||||
|
||||
copyList = ["CREDITS.md", "CHANGELOG.md", "LICENSE.md", "requirements.txt"]
|
||||
iconList = ["novelwriter.ico", "x-novelwriter-project.ico"]
|
||||
cpIgnore = shutil.ignore_patterns("__pycache__")
|
||||
# Sort Out Licence Files
|
||||
# ======================
|
||||
|
||||
print("Copying: novelwriter")
|
||||
shutil.copytree("novelwriter", os.path.join(zipDir, "novelwriter"), ignore=cpIgnore)
|
||||
for copyFile in copyList:
|
||||
print("Copying: %s" % copyFile)
|
||||
shutil.copy2(copyFile, os.path.join(outDir, copyFile))
|
||||
for iconFile in iconList:
|
||||
print("Copying: %s" % iconFile)
|
||||
shutil.copy2(os.path.join("setup", "icons", iconFile), os.path.join(outDir, iconFile))
|
||||
|
||||
# Move assets to outDir as it should not be packed with the rest
|
||||
print("Copying: assets")
|
||||
os.rename(os.path.join(zipDir, "novelwriter", "assets"), os.path.join(outDir, "assets"))
|
||||
|
||||
print("Writing: __main__.py")
|
||||
writeFile(os.path.join(zipDir, "__main__.py"), (
|
||||
"#!/usr/bin/env python3\n"
|
||||
"\n"
|
||||
"import os\n"
|
||||
"import sys\n"
|
||||
"\n"
|
||||
"sys.path.insert(\n"
|
||||
" 0, os.path.abspath(\n"
|
||||
" os.path.join(os.path.dirname(__file__), os.path.pardir, \"lib\")\n"
|
||||
" )\n"
|
||||
")\n\n"
|
||||
"if __name__ == \"__main__\":\n"
|
||||
" import novelwriter\n"
|
||||
" novelwriter.main()\n"
|
||||
))
|
||||
print("")
|
||||
|
||||
pyzFile = os.path.join(outDir, "novelWriter.pyz")
|
||||
zipapp.create_archive(zipDir, target=pyzFile, interpreter="/usr/bin/env python3")
|
||||
os.rename(
|
||||
os.path.join(outDir, "LICENSE.txt"),
|
||||
os.path.join(outDir, "PYTHON-LICENSE.txt")
|
||||
)
|
||||
shutil.copyfile(
|
||||
os.path.join("setup", "iss_license.txt"),
|
||||
os.path.join(outDir, "LICENSES.txt")
|
||||
)
|
||||
|
||||
# Install Dependencies
|
||||
# ====================
|
||||
|
||||
print("")
|
||||
print("# Installing Dependencies")
|
||||
print("# =======================")
|
||||
print("")
|
||||
print("Install dependencies ...")
|
||||
|
||||
sysCmd = [sys.executable]
|
||||
sysCmd += "-m pip install -r requirements.txt --target".split()
|
||||
@@ -960,54 +944,143 @@ def makeSimplePackage(embedPython):
|
||||
print(str(exc))
|
||||
sys.exit(1)
|
||||
|
||||
for subDir in os.listdir(libDir):
|
||||
chkDir = os.path.join(libDir, subDir)
|
||||
if os.path.isdir(chkDir) and chkDir.endswith(".dist-info"):
|
||||
shutil.rmtree(chkDir)
|
||||
|
||||
print("Done")
|
||||
print("")
|
||||
|
||||
# Remove Unneeded Library Files
|
||||
# =============================
|
||||
# Update Launch File
|
||||
# ==================
|
||||
|
||||
delQtLibs = [
|
||||
"opengl32sw.dll",
|
||||
"Qt5DBus.dll",
|
||||
"Qt5Designer.dll",
|
||||
"Qt5Network.dll",
|
||||
"Qt5OpenGL.dll",
|
||||
"Qt5Qml.dll",
|
||||
"Qt5QmlModels.dll",
|
||||
"Qt5QmlWorkerScript.dll",
|
||||
"Qt5Quick.dll",
|
||||
"Qt5Quick3D.dll",
|
||||
"Qt5Quick3DAssetImport.dll",
|
||||
"Qt5Quick3DRender.dll",
|
||||
"Qt5Quick3DRuntimeRender.dll",
|
||||
"Qt5Quick3DUtils.dll",
|
||||
"Qt5QuickControls2.dll",
|
||||
"Qt5QuickParticles.dll",
|
||||
"Qt5QuickShapes.dll",
|
||||
"Qt5QuickTemplates2.dll",
|
||||
"Qt5QuickTest.dll",
|
||||
"Qt5QuickWidgets.dll",
|
||||
"Qt5Sql.dll",
|
||||
]
|
||||
qtLibDir = os.path.join(libDir, "PyQt5", "Qt", "bin")
|
||||
for libName in delQtLibs:
|
||||
delFile = os.path.join(qtLibDir, libName)
|
||||
print("Updating starting script ...")
|
||||
|
||||
with open(os.path.join(outDir, "novelWriter.pyw"), mode="w") as outFile:
|
||||
outFile.write(
|
||||
"#!/usr/bin/env python3\n"
|
||||
"import os\n"
|
||||
"import sys\n"
|
||||
"\n"
|
||||
"os.curdir = os.path.abspath(os.path.dirname(__file__))\n"
|
||||
"sys.path.insert(0, os.path.join(os.curdir, \"lib\"))\n"
|
||||
"\n"
|
||||
"if __name__ == \"__main__\":\n"
|
||||
" import novelwriter\n"
|
||||
" novelwriter.main(sys.argv[1:])\n"
|
||||
)
|
||||
|
||||
print("Done")
|
||||
print("")
|
||||
|
||||
# Clean Up Files
|
||||
# ==============
|
||||
|
||||
def unlinkIfFound(delFile):
|
||||
if os.path.isfile(delFile):
|
||||
print("Deleting: %s" % delFile)
|
||||
os.unlink(delFile)
|
||||
print("Deleted: %s" % delFile)
|
||||
|
||||
qmlDir = os.path.join(libDir, "PyQt5", "Qt", "qml")
|
||||
if os.path.isdir(qmlDir):
|
||||
shutil.rmtree(qmlDir)
|
||||
def deleteFolder(delPath):
|
||||
if os.path.isdir(delPath):
|
||||
shutil.rmtree(delPath)
|
||||
print("Deleted: %s" % delPath)
|
||||
|
||||
print("Deleting Redundant Files")
|
||||
print("========================")
|
||||
print("")
|
||||
|
||||
print("Dictionaries")
|
||||
dictDir = os.path.join(libDir, "enchant", "data", "mingw64", "share", "enchant", "hunspell")
|
||||
for dictFile in os.listdir(dictDir):
|
||||
dictPath = os.path.join(dictDir, dictFile)
|
||||
if not os.path.isfile(dictPath):
|
||||
continue
|
||||
if dictFile.startswith("en_GB"):
|
||||
continue
|
||||
if dictFile.startswith("en_US"):
|
||||
continue
|
||||
unlinkIfFound(dictPath)
|
||||
|
||||
print("Translations")
|
||||
qmDir = os.path.join(libDir, "PyQt5", "Qt5", "translations")
|
||||
for qmFile in os.listdir(qmDir):
|
||||
qmPath = os.path.join(qmDir, qmFile)
|
||||
if not os.path.isfile(qmPath):
|
||||
continue
|
||||
if qmFile.startswith("qtbase"):
|
||||
continue
|
||||
unlinkIfFound(qmPath)
|
||||
|
||||
print("")
|
||||
print("Done!")
|
||||
|
||||
delQt5 = [
|
||||
"Qt5Bluetooth", "Qt5DBus", "Qt5Designer", "Qt5Designer", "Qt5Help", "Qt5Location",
|
||||
"Qt5Multimedia", "Qt5MultimediaWidgets", "Qt5Network", "Qt5Nfc", "Qt5OpenGL",
|
||||
"Qt5Positioning", "Qt5PositioningQuick", "Qt5Qml", "Qt5QmlModels", "Qt5QmlWorkerScript",
|
||||
"Qt5Quick", "Qt5Quick3D", "Qt5Quick3DAssetImport", "Qt5Quick3DRender",
|
||||
"Qt5Quick3DRuntimeRender", "Qt5Quick3DUtils", "Qt5QuickControls2", "Qt5QuickParticles",
|
||||
"Qt5QuickShapes", "Qt5QuickTemplates2", "Qt5QuickTest", "Qt5QuickWidgets", "Qt5Sensors",
|
||||
"Qt5SerialPort", "Qt5Sql", "Qt5Test", "Qt5TextToSpeech", "Qt5WebChannel", "Qt5WebSockets",
|
||||
"Qt5WebView", "Qt5Xml", "Qt5XmlPatterns"
|
||||
]
|
||||
pyQt5Dir = os.path.join(libDir, "PyQt5")
|
||||
bindDir = os.path.join(pyQt5Dir, "bindings")
|
||||
qt5Dir = os.path.join(pyQt5Dir, "Qt5")
|
||||
binDir = os.path.join(qt5Dir, "bin")
|
||||
plugDir = os.path.join(qt5Dir, "plugins")
|
||||
|
||||
delFiles = [
|
||||
os.path.join(binDir, "opengl32sw.dll")
|
||||
]
|
||||
delFolders = [
|
||||
os.path.join(qt5Dir, "qml"),
|
||||
os.path.join(plugDir, "geoservices"),
|
||||
os.path.join(plugDir, "playlistformats"),
|
||||
os.path.join(plugDir, "renderers"),
|
||||
os.path.join(plugDir, "sensorgestures"),
|
||||
os.path.join(plugDir, "sensors"),
|
||||
os.path.join(plugDir, "sqldrivers"),
|
||||
os.path.join(plugDir, "texttospeech"),
|
||||
os.path.join(plugDir, "webview"),
|
||||
]
|
||||
|
||||
for qt5Item in delQt5:
|
||||
print("Qt5 Component %s" % qt5Item)
|
||||
qtItem = qt5Item.replace("Qt5", "Qt")
|
||||
unlinkIfFound(os.path.join(binDir, qt5Item+".dll"))
|
||||
unlinkIfFound(os.path.join(pyQt5Dir, qtItem+".pyd"))
|
||||
unlinkIfFound(os.path.join(pyQt5Dir, qtItem+".pyi"))
|
||||
deleteFolder(os.path.join(bindDir, qtItem))
|
||||
print("")
|
||||
|
||||
print("Additional Files")
|
||||
for delItem in delFiles:
|
||||
unlinkIfFound(delItem)
|
||||
print("")
|
||||
|
||||
print("Additional Folders")
|
||||
for delItem in delFolders:
|
||||
deleteFolder(delItem)
|
||||
print("")
|
||||
|
||||
print("Done")
|
||||
print("")
|
||||
|
||||
print("Running Inno Setup")
|
||||
print("##################")
|
||||
print("")
|
||||
|
||||
# Read the iss template
|
||||
issData = readFile(os.path.join("setup", "win_setup_embed.iss"))
|
||||
issData = issData.replace(r"%%version%%", packVersion)
|
||||
issData = issData.replace(r"%%dir%%", os.getcwd())
|
||||
writeFile("setup.iss", issData)
|
||||
print("")
|
||||
|
||||
try:
|
||||
subprocess.call(["iscc", "setup.iss"])
|
||||
except Exception as exc:
|
||||
print("Inno Setup failed with error:")
|
||||
print(str(exc))
|
||||
sys.exit(1)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -1439,40 +1512,6 @@ def winUninstall():
|
||||
return
|
||||
|
||||
|
||||
# =============================================================================================== #
|
||||
# Windows Installers
|
||||
# =============================================================================================== #
|
||||
|
||||
##
|
||||
# Inno Setup Builder (setup-pyz)
|
||||
##
|
||||
|
||||
def innoSetup():
|
||||
"""Run the Inno Setup tool to build a setup.exe file for Windows based on the pyz package.
|
||||
"""
|
||||
print("")
|
||||
print("Running Inno Setup")
|
||||
print("##################")
|
||||
print("")
|
||||
|
||||
# Read the iss template
|
||||
numVers, _, _ = extractVersion()
|
||||
issData = readFile(os.path.join("setup", "win_setup_pyz.iss"))
|
||||
issData = issData.replace(r"%%version%%", numVers)
|
||||
issData = issData.replace(r"%%dir%%", os.getcwd())
|
||||
writeFile("setup.iss", issData)
|
||||
print("")
|
||||
|
||||
try:
|
||||
subprocess.call(["iscc", "setup.iss"])
|
||||
except Exception as exc:
|
||||
print("Inno Setup failed with error:")
|
||||
print(str(exc))
|
||||
sys.exit(1)
|
||||
|
||||
return
|
||||
|
||||
|
||||
# =============================================================================================== #
|
||||
# Process Command Line
|
||||
# =============================================================================================== #
|
||||
@@ -1565,11 +1604,8 @@ if __name__ == "__main__":
|
||||
" build-ubuntu Build a .deb packages Launchpad. Add --sign to ",
|
||||
" sign package. Add --first to set build number to 0.",
|
||||
" Add --snapshot to make a snapshot package.",
|
||||
" build-pyz Build a .pyz package in a folder with all dependencies",
|
||||
" using the zipapp tool. On Windows, python embeddable is",
|
||||
" added to the folder.",
|
||||
" setup-pyz Build a Windows executable installer from a zipapp package",
|
||||
" using Inno Setup. Must run 'build-pyz' first.",
|
||||
" build-win-exe Build a setup.exe file with Python embedded for Windows.",
|
||||
" The package must be built from a minimal windows zip file.",
|
||||
"",
|
||||
"System Install:",
|
||||
"",
|
||||
@@ -1589,11 +1625,6 @@ if __name__ == "__main__":
|
||||
"",
|
||||
]
|
||||
|
||||
# Flags and Variables
|
||||
makeSetupPyz = False
|
||||
simplePack = False
|
||||
embedPython = False
|
||||
|
||||
# General
|
||||
# =======
|
||||
|
||||
@@ -1668,11 +1699,10 @@ if __name__ == "__main__":
|
||||
print("ERROR: Command 'build-ubuntu' can only be used on Linux")
|
||||
sys.exit(1)
|
||||
|
||||
if "build-pyz" in sys.argv:
|
||||
sys.argv.remove("build-pyz")
|
||||
simplePack = True
|
||||
if hostOS == OS_WIN:
|
||||
embedPython = True
|
||||
if "build-win-exe" in sys.argv:
|
||||
sys.argv.remove("build-win-exe")
|
||||
makeWindowsEmbedded(sys.argv)
|
||||
sys.exit(0) # Don't continue execution
|
||||
|
||||
# General Installers
|
||||
# ==================
|
||||
@@ -1709,27 +1739,8 @@ if __name__ == "__main__":
|
||||
print("ERROR: Command 'win-uninstall' can only be used on Windows")
|
||||
sys.exit(1)
|
||||
|
||||
# Windows Setup Installer
|
||||
# =======================
|
||||
|
||||
if "setup-pyz" in sys.argv:
|
||||
sys.argv.remove("setup-pyz")
|
||||
if hostOS == OS_WIN:
|
||||
makeSetupPyz = True
|
||||
else:
|
||||
print("Error: Command 'setup-pyz' for Inno Setup is Windows only.")
|
||||
sys.exit(1)
|
||||
|
||||
# Actions
|
||||
# =======
|
||||
# For functions that are controlled by multiple flags, or need to be
|
||||
# run in a specific order.
|
||||
|
||||
if simplePack:
|
||||
makeSimplePackage(embedPython)
|
||||
|
||||
if makeSetupPyz:
|
||||
innoSetup()
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
# Nothing more to do
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
novelWriter License
|
||||
|
||||
Copyright (C) 2018-2022 Veronica Berglyd Olsen
|
||||
License: GPL v3+ <https://www.gnu.org/licenses/gpl-3.0.html>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Dependencies
|
||||
|
||||
Qt5
|
||||
Copyright: Qt Company
|
||||
Website: <https://www.qt.io/>
|
||||
License: LGPL v3 <https://www.gnu.org/licenses/lgpl-3.0.html>
|
||||
|
||||
PyQt5 / PyQt5-sip
|
||||
Copyright: Riverbank Computing
|
||||
Website: <https://www.riverbankcomputing.com/software/pyqt/>
|
||||
License: GPL v3 <https://www.gnu.org/licenses/gpl-3.0.html>
|
||||
|
||||
lxml
|
||||
Copyright: Infrae
|
||||
Website: <https://lxml.de/>
|
||||
License: BSD
|
||||
|
||||
Enchant
|
||||
Copyright: Dom Lachowicz
|
||||
Website: <https://abiword.github.io/enchant/>
|
||||
License: LGPL v2.1 <https://www.gnu.org/licenses/lgpl-2.1.html>
|
||||
|
||||
PyEnchant
|
||||
Copyright: Dimitri Merejkowsky
|
||||
Website: <https://pyenchant.github.io/pyenchant/>
|
||||
License: LGPL v2.1 <https://www.gnu.org/licenses/lgpl-2.1.html>
|
||||
|
||||
Typicons
|
||||
Copyright: Stephen Hutchings
|
||||
Website: <https://www.s-ings.com/typicons/>
|
||||
License: CC BY-SA 4.0 <http://creativecommons.org/licenses/by-sa/4.0/>
|
||||
@@ -5,12 +5,10 @@
|
||||
#define nwAppName "novelWriter"
|
||||
#define nwAppVersion "%%version%%"
|
||||
#define nwAppPublisher "novelWriter"
|
||||
#define nwAppURL "http://novelWriter.io"
|
||||
#define nwAppExeName "novelWriter.pyz"
|
||||
#define nwAppURL "https://novelWriter.io"
|
||||
#define nwAppExeName "novelWriter.pyw"
|
||||
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId={{459A75D0-951F-4932-9809-6002EC8E733E}
|
||||
AppName={#nwAppName}
|
||||
AppVersion={#nwAppVersion}
|
||||
@@ -19,15 +17,14 @@ AppPublisher={#nwAppPublisher}
|
||||
AppPublisherURL={#nwAppURL}
|
||||
AppSupportURL={#nwAppURL}
|
||||
AppUpdatesURL={#nwAppURL}
|
||||
SetupIconFile=setup\icons\novelwriter.ico
|
||||
DefaultDirName={autopf}\{#nwAppName}
|
||||
LicenseFile=setup\iss_license.txt
|
||||
DisableProgramGroupPage=yes
|
||||
; The [Icons] "quicklaunchicon" entry uses {userappdata} but its [Tasks] entry has a proper IsAdminInstallMode Check.
|
||||
UsedUserAreasWarning=no
|
||||
; Uncomment the following line to run in non administrative install mode (install for current user only.)
|
||||
;PrivilegesRequired=lowest
|
||||
PrivilegesRequiredOverridesAllowed=dialog
|
||||
OutputDir={#nwAppDir}
|
||||
OutputBaseFilename=novelwriter-{#nwAppVersion}-win10-amd64-pyz-setup
|
||||
OutputBaseFilename=novelwriter-{#nwAppVersion}-win10-amd64-standalone-setup
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
WizardStyle=modern
|
||||
@@ -56,4 +53,4 @@ Root: HKA; Subkey: "Software\Classes\.nwx\OpenWithProgids"; ValueType: string; V
|
||||
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx"; ValueType: string; ValueName: ""; ValueData: "novelWriter Project File"; Flags: uninsdeletekey
|
||||
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\assets\icons\x-novelwriter-project.ico"
|
||||
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\pythonw.exe"" ""{app}\{#nwAppExeName}"" ""%1"""
|
||||
Root: HKA; Subkey: "Software\Classes\Applications\{#nwAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".nwx"; ValueData: ""
|
||||
Root: HKA; Subkey: "Software\Classes\Applications\{#nwAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".nwx"; ValueData: ""; Flags: uninsdeletekey
|
||||
Reference in New Issue
Block a user