diff --git a/.flake8 b/.flake8 index 7207bf81..bdb25ca4 100644 --- a/.flake8 +++ b/.flake8 @@ -7,7 +7,6 @@ exclude = FDevIDs/ venv/ .venv/ - wix/ hotkey/darwin.py # FIXME: Check under macOS VM at some point # Show exactly where in a line the error happened diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index fc34c4bd..eaf29244 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -50,7 +50,6 @@ jobs: --exclude=pyproject.toml \ --exclude=scripts \ --exclude=tests \ - --exclude=wix \ EDMarketConnector mv ../EDMarketConnector-release-${{ needs.variables.outputs.sem_ver }}.tar.gz . @@ -92,7 +91,7 @@ jobs: # directory. # NB: If this gets too long it can cause zip 'Command Line Error', # presumably due to a Windows CL length limit. - exclusions: 'EDMarketConnector/EDMarketConnector-release-*.* EDMarketConnector/.editorconfig EDMarketConnector/.flake8 EDMarketConnector/.git* EDMarketConnector/.mypy.ini EDMarketConnector/.pre-commit-config.yaml EDMarketConnector/build.py EDMarketConnector/*.manifest EDMarketConnector/coriolis-data/ EDMarketConnector/img/ EDMarketConnector/pyproject.toml EDMarketConnector/scripts/ EDMarketConnector/tests/ EDMarketConnector/wix/' + exclusions: 'EDMarketConnector/EDMarketConnector-release-*.* EDMarketConnector/.editorconfig EDMarketConnector/.flake8 EDMarketConnector/.git* EDMarketConnector/.mypy.ini EDMarketConnector/.pre-commit-config.yaml EDMarketConnector/build.py EDMarketConnector/*.manifest EDMarketConnector/coriolis-data/ EDMarketConnector/img/ EDMarketConnector/pyproject.toml EDMarketConnector/scripts/ EDMarketConnector/tests/' - uses: actions/setup-python@v4 with: @@ -114,12 +113,17 @@ jobs: run: | python build.py + - name: InnoSetup + uses: nadeemjazmawe/inno-setup-action-cli@v6.0.5 + with: + filepath: './EDMC_Installer_Config.iss' + - name: Upload build files uses: actions/upload-artifact@v3 with: name: Built files path: | - EDMarketConnector_win_*.msi + EDMarketConnector_Installer_*.exe EDMarketConnector-release-*.zip release: @@ -136,7 +140,7 @@ jobs: path: ./ - name: Hash files - run: sha256sum EDMarketConnector_win_*.msi EDMarketConnector-release-*.{zip,tar.gz} > ./hashes.sum + run: sha256sum EDMarketConnector_Installer_*.exe EDMarketConnector-release-*.{zip,tar.gz} > ./hashes.sum - name: Create Draft Release uses: "softprops/action-gh-release@v1" @@ -146,7 +150,7 @@ jobs: prerelease: true discussion_category_name: "Announcement" files: | - ./EDMarketConnector_win_*.msi + ./EDMarketConnector_Installer_*.exe ./EDMarketConnector-release-*.zip ./EDMarketConnector-release-*.tar.gz ./hashes.sum diff --git a/.gitignore b/.gitignore index 4b13d5c3..720a84b3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,7 @@ dump *.pyo *.dll *.pdb -*.msi -*.wixobj +EDMarketConnector_Installer_*.exe appcast_win_*.xml appcast_mac_*.xml EDMarketConnector.VisualElementsManifest.xml @@ -24,5 +23,3 @@ venv/ htmlcov/ .ignored .coverage -EDMarketConnector.wxs -wix/components.wxs diff --git a/EDMC_Installer_Config.iss b/EDMC_Installer_Config.iss new file mode 100644 index 00000000..ee3556b7 --- /dev/null +++ b/EDMC_Installer_Config.iss @@ -0,0 +1,57 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "EDMarketConnector" +#define MyAppVersion "5.9.1-alpha1" +#define MyAppPublisher "EDCD" +#define MyAppURL "https://edcd.github.io/" +#define SuppURL "https://github.com/EDCD/EDMarketConnector/" +#define MyAppExeName "EDMarketConnector.exe" + +[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={{5B5AB12D-23A6-47BB-B937-07F23FF0BF86} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#SuppURL} +AppUpdatesURL={#SuppURL} +AppCopyright=Copyright (C) 2015-2019 Jonathan Harris, 2020-2023 EDCD +AllowUNCPath=no +AllowNetworkDrive=no +DefaultDirName={autopf}\{#MyAppName} +DisableProgramGroupPage=yes +DirExistsWarning=yes +AllowNoIcons=yes +; Uncomment the following line to run in non administrative install mode (install for current user only.) +;PrivilegesRequired=lowest +OutputBaseFilename=EDMarketConnector_Installer_{#MyAppVersion} +SetupIconFile=dist.win32\EDMarketConnector.ico +Compression=lzma2/max +SolidCompression=yes +WizardStyle=modern +InfoBeforeFile=dist.win32\Changelog.md +OutputDir=. +LicenseFile=LICENSE + + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "dist.win32\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +Source: "dist.win32\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent diff --git a/build.py b/build.py index ee5eea0e..1d2b55a7 100644 --- a/build.py +++ b/build.py @@ -1,25 +1,20 @@ """ -build.py - Build the Installer. +build.py - Build the program EXE. Copyright (c) EDCD, All Rights Reserved Licensed under the GNU General Public License. See LICENSE file. """ import os -import re import shutil -import subprocess import sys import pathlib import py2exe -from os.path import exists, join, isdir -from tempfile import gettempdir -from lxml import etree +from os.path import join, isdir from config import ( appcmdname, appname, appversion, - appversion_nobuild, copyright, git_shorthash_from_head, ) @@ -91,36 +86,6 @@ def generate_data_files( return data_files -def windows_installer_display_lang(app_name: str, filename: str) -> None: - """Configure the Windows Installer Display Language.""" - lcids = [ - int(x) - for x in re.search( # type: ignore - r'Languages\s*=\s*"(.+?)"', open(f"{app_name}.wxs", encoding="UTF8").read() - ) - .group(1) - .split(",") - ] - assert lcids[0] == 1033, f"Default language is {lcids[0]}, should be 1033 (en_US)" - shutil.copyfile(filename, join(gettempdir(), f"{app_name}_1033.msi")) - for lcid in lcids[1:]: - shutil.copyfile( - join(gettempdir(), f"{app_name}_1033.msi"), - join(gettempdir(), f"{app_name}_{lcid}.msi"), - ) - # Don't care about codepage because the displayed strings come from msiexec not our msi - os.system( - rf'cscript /nologo "{SDKPATH}\WiLangId.vbs" {gettempdir()}\{app_name}_{lcid}.msi Product {lcid}' - ) - os.system( - rf'"{SDKPATH}\MsiTran.Exe" -g {gettempdir()}\{app_name}_1033.msi' - rf" {gettempdir()}\{app_name}_{lcid}.msi {gettempdir()}\{lcid}.mst" - ) - os.system( - rf'cscript /nologo "{SDKPATH}\WiSubStg.vbs" {filename} {gettempdir()}\{lcid}.mst {lcid}' - ) - - if __name__ == "__main__": DIST_DIR: str = "dist.win32" GITVERSION_FILENAME: str = system_check(DIST_DIR) @@ -201,120 +166,3 @@ if __name__ == "__main__": data_files=DATA_FILES, options=OPTIONS, ) - - ########################################################################### - # Build installer(s) - ########################################################################### - template_file = pathlib.Path("wix/template.wxs") - components_file = pathlib.Path("wix/components.wxs") - final_wxs_file = pathlib.Path("EDMarketConnector.wxs") - - # Use heat.exe to generate the Component for all files inside dist.win32 - heat_command = [ - str(join(WIXPATH, "heat.exe")), - "dir", - str(DIST_DIR), - "-ag", - "-sfrag", - "-srid", - "-suid", - "-out", - str(components_file), - ] - subprocess.run(heat_command, check=True) - - component_tree = etree.parse(str(components_file)) - # Modify component_tree as described in the original code... - - directory_win32 = component_tree.find( - './/{*}Directory[@Id="dist.win32"][@Name="dist.win32"]' - ) - if directory_win32 is None: - raise ValueError(f'{components_file}: Expected Directory with Id="dist.win32"') - - directory_win32.set("Id", "INSTALLDIR") - directory_win32.set("Name", "$(var.PRODUCTNAME)") - - main_executable = directory_win32.find( - './/{*}Component[@Id="EDMarketConnector.exe"]' - ) - if main_executable is None: - raise ValueError( - f'{components_file}: Expected Component with Id="EDMarketConnector.exe"' - ) - - main_executable.set("Id", "MainExecutable") - main_executable.set("Guid", "{D33BB66E-9664-4AB6-A044-3004B50A09B0}") - shortcut = etree.SubElement( - main_executable, - "Shortcut", - nsmap=main_executable.nsmap, - attrib={ - "Id": "MainExeShortcut", - "Directory": "ProgramMenuFolder", - "Name": "$(var.PRODUCTLONGNAME)", - "Description": "Downloads station data from Elite: Dangerous", - "WorkingDirectory": "INSTALLDIR", - "Icon": "EDMarketConnector.exe", - "IconIndex": "0", - "Advertise": "yes", - }, - ) - # Now insert the appropriate parts as a child of the ProgramFilesFolder part - # of the template. - template_tree = etree.parse(str(template_file)) - program_files_folder = template_tree.find( - './/{*}Directory[@Id="ProgramFilesFolder"]' - ) - if program_files_folder is None: - raise ValueError( - f'{template_file}: Expected Directory with Id="ProgramFilesFolder"' - ) - - program_files_folder.insert(0, directory_win32) - # Append the Feature/ComponentRef listing to match - feature = template_tree.find('.//{*}Feature[@Id="Complete"][@Level="1"]') - if feature is None: - raise ValueError( - f'{template_file}: Expected Feature element with Id="Complete" Level="1"' - ) - # This isn't part of the components - feature.append( - etree.Element( - "ComponentRef", - attrib={"Id": "RegistryEntries"}, - nsmap=directory_win32.nsmap, - ) - ) - for c in directory_win32.findall(".//{*}Component"): - feature.append( - etree.Element( - "ComponentRef", attrib={"Id": c.get("Id")}, nsmap=directory_win32.nsmap - ) - ) - - # Insert what we now have into the template and write it out - template_tree.write( - str(final_wxs_file), encoding="utf-8", pretty_print=True, xml_declaration=True - ) - - candle_command = rf'"{WIXPATH}\candle.exe" {appname}.wxs' - subprocess.run(candle_command, shell=True, check=True) - - if not exists(f"{appname}.wixobj"): - raise AssertionError(f"No {appname}.wixobj: candle.exe failed?") - - package_filename = f"{appname}_win_{appversion_nobuild()}.msi" - light_command = ( - rf'"{WIXPATH}\light.exe" -b {DIST_DIR}\ -sacl -spdb ' - rf"-sw1076 {appname}.wixobj -out {package_filename}" - ) - subprocess.run(light_command, shell=True, check=True) - - if not exists(package_filename): - raise AssertionError(f"light.exe failed, no {package_filename}") - - # Seriously, this is how you make Windows Installer use the user's display language for its dialogs. What a crock. - # http://www.geektieguy.com/2010/03/13/create-a-multi-lingual-multi-language-msi-using-wix-and-custom-build-scripts - windows_installer_display_lang(appname, package_filename) - ########################################################################### diff --git a/docs/Releasing.md b/docs/Releasing.md index 0bd14838..4c2217bf 100644 --- a/docs/Releasing.md +++ b/docs/Releasing.md @@ -26,8 +26,6 @@ This is principally due to the Windows Registry handling in You will need several pieces of software installed, or the files from their .zip archives, in order to build the .exe and generate the .msi -1. [WiX Toolset](https://wixtoolset.org/): 3.11.2 is the most recently tested - version. 1. [WinSparkle](https://github.com/vslavik/winsparkle): `winsparkle.dll` and `winsparkle.pdb` from the release's .zip file. v0.7.0 is the most recently tested version. Copy the two files, found at `\\Release`, @@ -61,9 +59,8 @@ You will need several pieces of software installed, or the files from their If you are using different versions of any of these tools then please ensure that the paths where they're installed match the associated lines in -`build.py`. i.e. if you're using later WiX you might need to edit -the WIXPATH line, and likewise the SDKPATH line if you're using a later -Windows SDK kit. +`build.py`. i.e. if you're using later Windows SDK kit you might need to edit +the SDKPATH line. # Version Strings @@ -149,43 +146,6 @@ well then you will need to properly add it to the build process. You'll need to add it in `build.py` so that py2exe includes it in the build. Add the file to the DATA_FILES statement. -### WiX - -You will *also* need to add the file to the `EDMarketConnector.wxs` file so -that it's actually included in the installer. - -1. Location the the appropriate part of the: - - ```xml - - ``` - section and add a new sub-section: - - ```xml - - - - ``` - - Note that you only need `Id=""` if the filename itself - is not a valid Id, e.g. because it contains spaces. - - If the new file is in a new sub-directory then you'll need to add that as - well. See the `L10n` example. - -2. Now find the: - - ```xml - - ``` - - section and add an appropriate line to it. Remember to use either the - specific Id you set above or the filename (without directory) for this: - - ```xml - - ``` - # Pre-Packaging Steps Before you create a new install each time you should: @@ -284,26 +244,6 @@ INFO:runtime:Found 695 modules, 60 are missing, 0 may be missing ... Building 'dist.win32\EDMC.exe'. Building 'dist.win32\EDMarketConnector.exe'. -... -Windows Installer XML Toolset Toolset Harvester version 3.11.2.4516 -Copyright (c) .NET Foundation and contributors. All rights reserved. - -Windows Installer XML Toolset Compiler version 3.11.2.4516 -Copyright (c) .NET Foundation and contributors. All rights reserved. - -EDMarketConnector.wxs -Windows Installer XML Toolset Linker version 3.11.2.4516 -Copyright (c) .NET Foundation and contributors. All rights reserved. -... -Package language = 1033,1029,1031,1034,1035,1036,1038,1040,1041,1043,1045,1046,1049,1058,1062,2052,2070,2074,6170,1060,1053,18,0, ProductLanguage = 1029, Database codepage = 0 -MsiTran V 5.0 -Copyright (c) Microsoft Corporation. All Rights Reserved -... -DonePackage language = 1033,1029,1031,1034,1035,1036,1038,1040,1041,1043,1045,1046,1049,1058,1062,2052,2070,2074,6170,1060,1053,18,0, ProductLanguage = 0, Database codepage = 0 -MsiTran V 5.0 -Copyright (c) Microsoft Corporation. All Rights Reserved - -Done ``` **Do check the output** for things like not properly specifying extra files @@ -319,19 +259,16 @@ Check that the `EDMarketConnector.exe` in the `dist.win32` folder does run without errors. Finally, uninstall your current version of ED Market Connector and re-install -using the newly generated `EDMarketConnector_win_4.0.2.msi` file. Check the +using the newly generated `EDMarketConnector_installer_4.0.2.exe` file. Check the resulting installation does work (the installer will run the program for you). -If it doesn't then check if there are any files, particularly `.dll` or `.pyd` -files in `dist.win32` that aren't yet specified in the `EDMarketConnector.wxs` -file, i.e. they're not packaged into the installer. Update `edmarketconnector.xml` once more to set the `length=` attribute of the -enclosure to match the file size of the `EDMarketConnector_win_4.0.2.msi` file. +enclosure to match the file size of the `EDMarketConnector_win_4.0.2.exe` file. The git commit for this should end up being the release tag as below. # Distribution -Whether you built it manually or automatically you **MUST** test the `.msi` +Whether you built it manually or automatically you **MUST** test the `.exe` installer file prior to making the release live. Once that is done then for manually built installers: diff --git a/docs/Translations.md b/docs/Translations.md index 6516269d..333ce27b 100644 --- a/docs/Translations.md +++ b/docs/Translations.md @@ -101,35 +101,3 @@ To add a new language to the app: 1. Be sure to go through and Finalize any phrases that shouldn't be translated. See [Translations]() in the Wiki. Remember that until there are translations all strings will default to the English version (actually the key, which is always specified in English). - -1. You need to get the new `.strings` file added to the files the installer will install: - 1. Edit `EDMarketConnector.wxs` to add an appropriate section to the: - - `` - section, e.g.: - - - - ` - 1. You also need to add a line in the: - - - - section, e.g.: - - - Note how the `-` characters have been changed to `_`. If needs be run the build process once and look out for - lines like: - - \EDMarketConnector\EDMarketConnector.wxs(264) : error LGHT0204 : ICE21: Component: 'sr_Latn_BA.strings' does not belong to any Feature. - to see what the applicable string is. - -1. You will also want to add it to the installer's languages. This is simple enough, only requiring you add a number to an array in `EDMarketConnector.wxs`. - - 1. In `EDMarketConnector.wxs` find the line beginning `Languages="1033,`, e.g. - - Languages="1033,1029,1031,1034,1035,1036,1038,1040,1041,1043,1045,1046,1049,1058,1062,2052,2070,2074,6170,0" /> - 1. Now you'll need to consult the latest [[MS-LCID]: Windows Language Code Identifier (LCID) Reference](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f) for the correct numerical code to add to the list. - 1. Convert the hexadecimal Language ID to the equivalent in decimal. - 1. Add the new decimal value as the last but one value in the list, keeping the `,0` at the end. - 1. Update the comment on the next line to reflect what you added. diff --git a/installer.py b/installer.py new file mode 100644 index 00000000..8fd3acf3 --- /dev/null +++ b/installer.py @@ -0,0 +1,42 @@ +""" +installer.py - Build the Installer. + +Copyright (c) EDCD, All Rights Reserved +Licensed under the GNU General Public License. +See LICENSE file. +""" +import os +import subprocess + + +def run_inno_setup_installer(iss_file_path: str) -> None: + """Run the Inno installer, building the installation exe.""" + # Get the path to the Inno Setup compiler (iscc.exe) (Currently set to default path) + inno_setup_compiler_path: str = "C:\\Program Files (x86)\\Inno Setup 6\\ISCC.exe" + + # Check if the Inno Setup compiler executable exists + if not os.path.isfile(inno_setup_compiler_path): + print(f"Error: Inno Setup compiler not found at '{inno_setup_compiler_path}'.") + return + + # Check if the provided .iss file exists + if not os.path.isfile(iss_file_path): + print(f"Error: The provided .iss file '{iss_file_path}' not found.") + return + + # Run the Inno Setup compiler with the provided .iss file + try: + subprocess.run([inno_setup_compiler_path, iss_file_path], check=True) + except subprocess.CalledProcessError as e: + print( + f"Error: Inno Setup compiler returned an error (exit code {e.returncode}):" + ) + print(e.output.decode()) + except Exception as e: + print(f"Error: An unexpected error occurred: {e}") + + +if __name__ == "__main__": + # Replace 'your_iss_file.iss' with the path to your actual .iss file + iss_file_path: str = "./EDMC_Installer_Config.iss" + run_inno_setup_installer(iss_file_path) diff --git a/requirements-dev.txt b/requirements-dev.txt index f46ff107..c2ca4a6b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -34,11 +34,7 @@ pre-commit==3.3.3 grip==4.6.1 # Packaging -# Used to put together a WiX configuration from template/auto-gen -lxml==4.9.3 # We only need py2exe on windows. -# Pre-release version addressing semantic_version 2.9.0+ issues: -# py2exe==0.13.0.0; sys_platform == 'win32' # Testing diff --git a/wix/static-EDMarketConnector.wxs b/wix/static-EDMarketConnector.wxs deleted file mode 100644 index a0178579..00000000 --- a/wix/static-EDMarketConnector.wxs +++ /dev/null @@ -1,720 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION - - - - - WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION - - - - - - - - - NOT Installed - - - - - - - - - - NOT Installed AND LAUNCH ~= "yes" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wix/template.wxs b/wix/template.wxs deleted file mode 100644 index 82da0c4e..00000000 --- a/wix/template.wxs +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION - - - - - WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION - - - - - - - - - NOT Installed - - - - - - - - - - NOT Installed AND LAUNCH ~= "yes" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -