mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-11 16:57:51 -06:00
Merge branch 'main' into GH-12582_fix_uninstall_by_other
# Conflicts: # packaging/NSIS/Ultimaker-Cura.nsi.jinja
This commit is contained in:
commit
cee219f65b
199 changed files with 4963 additions and 3165 deletions
|
@ -1,10 +1,11 @@
|
|||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Cura's build system is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
!define APP_NAME "{{ app_name }} {{ version_major }}.{{ version_minor }}.{{ version_patch }}"
|
||||
!define APP_NAME "{{ app_name }}"
|
||||
!define COMP_NAME "{{ company }}"
|
||||
!define WEB_SITE "{{ web_site }}"
|
||||
!define VERSION "{{ version_major }}.{{ version_minor }}.{{ version_patch }}.{{ version_build }}"
|
||||
!define VERSION "{{ version }}"
|
||||
!define VIVERSION "{{ version_major }}.{{ version_minor }}.{{ version_patch }}.0"
|
||||
!define COPYRIGHT "Copyright (c) {{ year }} {{ company }}"
|
||||
!define DESCRIPTION "Application"
|
||||
!define LICENSE_TXT "{{ cura_license_file }}"
|
||||
|
@ -12,7 +13,7 @@
|
|||
!define MAIN_APP_EXE "{{ main_app }}"
|
||||
!define INSTALL_TYPE "SetShellVarContext all"
|
||||
!define REG_ROOT "HKCR"
|
||||
!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAIN_APP_EXE}"
|
||||
!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${APP_NAME}"
|
||||
!define UNINSTALL_PATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
|
||||
|
||||
!define REG_START_MENU "Start Menu Folder"
|
||||
|
@ -24,12 +25,12 @@ var SM_Folder
|
|||
|
||||
######################################################################
|
||||
|
||||
VIProductVersion "${VERSION}"
|
||||
VIAddVersionKey "ProductName" "${APP_NAME}"
|
||||
VIProductVersion "${VIVERSION}"
|
||||
VIAddVersionKey "ProductName" "{{ app_name }}"
|
||||
VIAddVersionKey "CompanyName" "${COMP_NAME}"
|
||||
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
|
||||
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
|
||||
VIAddVersionKey "FileVersion" "${VERSION}"
|
||||
VIAddVersionKey "FileVersion" "${VIVERSION}"
|
||||
|
||||
######################################################################
|
||||
|
||||
|
@ -38,7 +39,6 @@ Name "${APP_NAME}"
|
|||
Caption "${APP_NAME}"
|
||||
OutFile "${INSTALLER_NAME}"
|
||||
BrandingText "${APP_NAME}"
|
||||
InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" ""
|
||||
InstallDir "$PROGRAMFILES64\${APP_NAME}"
|
||||
|
||||
######################################################################
|
||||
|
@ -64,7 +64,7 @@ InstallDir "$PROGRAMFILES64\${APP_NAME}"
|
|||
|
||||
!ifdef REG_START_MENU
|
||||
!define MUI_STARTMENUPAGE_NODISABLE
|
||||
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "{{ app_name }}"
|
||||
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Ultimaker Cura"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${REG_ROOT}"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${UNINSTALL_PATH}"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${REG_START_MENU}"
|
||||
|
@ -113,8 +113,8 @@ CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE
|
|||
CreateShortCut "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
|
||||
|
||||
!ifdef WEB_SITE
|
||||
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
|
||||
CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url"
|
||||
WriteIniStr "$INSTDIR\Ultimaker Cura website.url" "InternetShortcut" "URL" "${WEB_SITE}"
|
||||
CreateShortCut "$SMPROGRAMS\$SM_Folder\Ultimaker Cura website.lnk" "$INSTDIR\Ultimaker Cura website.url"
|
||||
!endif
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
!endif
|
||||
|
@ -125,8 +125,8 @@ CreateShortCut "$SMPROGRAMS\{{ app_name }}\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP
|
|||
CreateShortCut "$SMPROGRAMS\{{ app_name }}\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
|
||||
|
||||
!ifdef WEB_SITE
|
||||
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
|
||||
CreateShortCut "$SMPROGRAMS\{{ app_name }}\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url"
|
||||
WriteIniStr "$INSTDIR\Ultimaker Cura website.url" "InternetShortcut" "URL" "${WEB_SITE}"
|
||||
CreateShortCut "$SMPROGRAMS\{{ app_name }}\Ultimaker Cura website.lnk" "$INSTDIR\Ultimaker Cura website.url"
|
||||
!endif
|
||||
!endif
|
||||
|
||||
|
@ -170,7 +170,7 @@ RmDir "$INSTDIR"
|
|||
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk"
|
||||
Delete "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk"
|
||||
!ifdef WEB_SITE
|
||||
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk"
|
||||
Delete "$SMPROGRAMS\$SM_Folder\Ultimaker Cura website.lnk"
|
||||
!endif
|
||||
RmDir "$SMPROGRAMS\$SM_Folder"
|
||||
!endif
|
||||
|
@ -179,7 +179,7 @@ RmDir "$SMPROGRAMS\$SM_Folder"
|
|||
Delete "$SMPROGRAMS\{{ app_name }}\${APP_NAME}.lnk"
|
||||
Delete "$SMPROGRAMS\{{ app_name }}\Uninstall ${APP_NAME}.lnk"
|
||||
!ifdef WEB_SITE
|
||||
Delete "$SMPROGRAMS\{{ app_name }}\${APP_NAME} Website.lnk"
|
||||
Delete "$SMPROGRAMS\{{ app_name }}\Ultimaker Cura website.lnk"
|
||||
!endif
|
||||
RmDir "$SMPROGRAMS\{{ app_name }}"
|
||||
!endif
|
||||
|
|
80
packaging/NSIS/create_windows_installer.py
Normal file
80
packaging/NSIS/create_windows_installer.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import os
|
||||
import argparse # Command line arguments parsing and help.
|
||||
import subprocess
|
||||
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
|
||||
def generate_nsi(source_path: str, dist_path: str, filename: str):
|
||||
dist_loc = Path(os.getcwd(), dist_path)
|
||||
source_loc = Path(os.getcwd(), source_path)
|
||||
instdir = Path("$INSTDIR")
|
||||
dist_paths = [p.relative_to(dist_loc.joinpath("Ultimaker-Cura")) for p in sorted(dist_loc.joinpath("Ultimaker-Cura").rglob("*")) if p.is_file()]
|
||||
mapped_out_paths = {}
|
||||
for dist_path in dist_paths:
|
||||
if "__pycache__" not in dist_path.parts:
|
||||
out_path = instdir.joinpath(dist_path).parent
|
||||
if out_path not in mapped_out_paths:
|
||||
mapped_out_paths[out_path] = [(dist_loc.joinpath("Ultimaker-Cura", dist_path), instdir.joinpath(dist_path))]
|
||||
else:
|
||||
mapped_out_paths[out_path].append((dist_loc.joinpath("Ultimaker-Cura", dist_path), instdir.joinpath(dist_path)))
|
||||
|
||||
rmdir_paths = set()
|
||||
for rmdir_f in mapped_out_paths.values():
|
||||
for _, rmdir_p in rmdir_f:
|
||||
for rmdir in rmdir_p.parents:
|
||||
rmdir_paths.add(rmdir)
|
||||
|
||||
rmdir_paths = sorted(list(rmdir_paths), reverse = True)[:-2] # Removes the `.` and `..` from the list
|
||||
|
||||
jinja_template_path = Path(source_loc.joinpath("packaging", "NSIS", "Ultimaker-Cura.nsi.jinja"))
|
||||
with open(jinja_template_path, "r") as f:
|
||||
template = Template(f.read())
|
||||
|
||||
|
||||
nsis_content = template.render(
|
||||
app_name = f"Ultimaker Cura {os.getenv('CURA_VERSION_FULL')}",
|
||||
main_app = "Ultimaker-Cura.exe",
|
||||
version = os.getenv('CURA_VERSION_FULL'),
|
||||
version_major = os.environ.get("CURA_VERSION_MAJOR"),
|
||||
version_minor = os.environ.get("CURA_VERSION_MINOR"),
|
||||
version_patch = os.environ.get("CURA_VERSION_PATCH"),
|
||||
company = "Ultimaker B.V.",
|
||||
web_site = "https://ultimaker.com",
|
||||
year = datetime.now().year,
|
||||
cura_license_file = str(source_loc.joinpath("packaging", "cura_license.txt")),
|
||||
compression_method = "LZMA", # ZLIB, BZIP2 or LZMA
|
||||
cura_banner_img = str(source_loc.joinpath("packaging", "NSIS", "cura_banner_nsis.bmp")),
|
||||
cura_icon = str(source_loc.joinpath("packaging", "icons", "Cura.ico")),
|
||||
mapped_out_paths = mapped_out_paths,
|
||||
rmdir_paths = rmdir_paths,
|
||||
destination = filename
|
||||
)
|
||||
|
||||
with open(dist_loc.joinpath("Ultimaker-Cura.nsi"), "w") as f:
|
||||
f.write(nsis_content)
|
||||
|
||||
shutil.copy(source_loc.joinpath("packaging", "NSIS", "fileassoc.nsh"), dist_loc.joinpath("fileassoc.nsh"))
|
||||
|
||||
|
||||
def build(dist_path: str):
|
||||
dist_loc = Path(os.getcwd(), dist_path)
|
||||
command = ["makensis", "/V2", "/P4", str(dist_loc.joinpath("Ultimaker-Cura.nsi"))]
|
||||
subprocess.run(command)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description = "Create Windows exe installer of Cura.")
|
||||
parser.add_argument("source_path", type=str, help="Path to Conan install Cura folder.")
|
||||
parser.add_argument("dist_path", type=str, help="Path to Pyinstaller dist folder")
|
||||
parser.add_argument("filename", type = str, help = "Filename of the exe (e.g. 'Ultimaker-Cura-5.1.0-beta-Windows-X64.exe')")
|
||||
args = parser.parse_args()
|
||||
generate_nsi(args.source_path, args.dist_path, args.filename)
|
||||
build(args.dist_path)
|
|
@ -1,78 +0,0 @@
|
|||
import shutil
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
- dist_loc: Location of distribution folder, as output by pyinstaller
|
||||
- nsi_jinja_loc: Jinja2 template to use
|
||||
- app_name: Should be "Ultimaker Cura".
|
||||
- main_app: Name of executable, e.g. Ultimaker-Cura.exe?
|
||||
- version_major: Major version number of Semver (e.g. 5).
|
||||
- version_minor: Minor version number of Semver (e.g. 0).
|
||||
- version_patch: Patch version number of Semver (e.g. 0).
|
||||
- version_build: A version number that gets manually incremented at each build.
|
||||
- company: Publisher of the application. Should be "Ultimaker B.V."
|
||||
- web_site: Website to find more information. Should be "https://ultimaker.com".
|
||||
- cura_license_file: Path to a license file in Cura. Should point to packaging/cura_license.txt in this repository.
|
||||
- compression_method: Compression algorithm to use to compress the data inside the executable. Should be ZLIB, ZBIP2 or LZMA.
|
||||
- cura_banner_img: Path to an image shown on the left in the installer. Should point to packaging/cura_banner_nsis.bmp in this repository.
|
||||
- icon_path: Path to the icon to use on the installer
|
||||
- destination: Where to put the installer after it's generated.
|
||||
` """
|
||||
for i, v in enumerate(sys.argv):
|
||||
print(f"{i} = {v}")
|
||||
dist_loc = Path(sys.argv[1])
|
||||
instdir = Path("$INSTDIR")
|
||||
dist_paths = [p.relative_to(dist_loc) for p in sorted(dist_loc.rglob("*")) if p.is_file()]
|
||||
mapped_out_paths = {}
|
||||
for dist_path in dist_paths:
|
||||
if "__pycache__" not in dist_path.parts:
|
||||
out_path = instdir.joinpath(dist_path).parent
|
||||
if out_path not in mapped_out_paths:
|
||||
mapped_out_paths[out_path] = [(dist_loc.joinpath(dist_path), instdir.joinpath(dist_path))]
|
||||
else:
|
||||
mapped_out_paths[out_path].append((dist_loc.joinpath(dist_path), instdir.joinpath(dist_path)))
|
||||
|
||||
rmdir_paths = set()
|
||||
for rmdir_f in mapped_out_paths.values():
|
||||
for _, rmdir_p in rmdir_f:
|
||||
for rmdir in rmdir_p.parents:
|
||||
rmdir_paths.add(rmdir)
|
||||
|
||||
rmdir_paths = sorted(list(rmdir_paths), reverse = True)[:-2]
|
||||
|
||||
jinja_template_path = Path(sys.argv[2])
|
||||
with open(jinja_template_path, "r") as f:
|
||||
template = Template(f.read())
|
||||
|
||||
nsis_content = template.render(
|
||||
app_name = sys.argv[3],
|
||||
main_app = sys.argv[4],
|
||||
version_major = sys.argv[5],
|
||||
version_minor = sys.argv[6],
|
||||
version_patch = sys.argv[7],
|
||||
version_build = sys.argv[8],
|
||||
company = sys.argv[9],
|
||||
web_site = sys.argv[10],
|
||||
year = datetime.now().year,
|
||||
cura_license_file = Path(sys.argv[11]),
|
||||
compression_method = sys.argv[12], # ZLIB, BZIP2 or LZMA
|
||||
cura_banner_img = Path(sys.argv[13]),
|
||||
cura_icon = Path(sys.argv[14]),
|
||||
mapped_out_paths = mapped_out_paths,
|
||||
rmdir_paths = rmdir_paths,
|
||||
destination = Path(sys.argv[15])
|
||||
)
|
||||
|
||||
with open(dist_loc.parent.joinpath(jinja_template_path.stem), "w") as f:
|
||||
f.write(nsis_content)
|
||||
|
||||
shutil.copy(Path(__file__).absolute().parent.joinpath("fileassoc.nsh"), dist_loc.parent.joinpath("fileassoc.nsh"))
|
||||
icon_path = Path(sys.argv[14])
|
||||
shutil.copy(icon_path, dist_loc.joinpath(icon_path.name))
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue