1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-15 00:30:33 +03:00

Merge pull request #2041 from Rixxan/enhancement/2040/build-system

#2040 Build System Overhaul
This commit is contained in:
Phoebe 2023-08-02 21:10:58 +02:00 committed by GitHub
commit 1c1b6fc190
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 338 additions and 1285 deletions

View File

@ -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

View File

@ -43,14 +43,13 @@ jobs:
--exclude=.git* \
--exclude=.mypy.ini \
--exclude=.pre-commit-config.yaml \
--exclude=Build-exe-and-msi.py \
--exclude=build.py \
--exclude=*.manifest \
--exclude=coriolis-data \
--exclude=img \
--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-exe-and-msi.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:
@ -112,14 +111,19 @@ jobs:
- name: Build EDMC
run: |
python Build-exe-and-msi.py
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

2
.gitignore vendored
View File

@ -11,10 +11,12 @@ dump
*.pdb
*.msi
*.wixobj
EDMarketConnector_Installer_*.exe
appcast_win_*.xml
appcast_mac_*.xml
EDMarketConnector.VisualElementsManifest.xml
*.zip
EDMC_Installer_Config.iss
.idea
.vscode

View File

@ -1,298 +0,0 @@
#!/usr/bin/env python3
"""Build to executables and MSI installer using py2exe and other tools."""
import os
import pathlib
import re
import shutil
import sys
from os.path import exists, isdir, join
from tempfile import gettempdir
from lxml import etree
from py2exe import freeze
from config import appcmdname, appname, appversion, appversion_nobuild, copyright, git_shorthash_from_head
from constants import GITVERSION_FILE
###########################################################################
# Check we're on a supported platform
###########################################################################
if sys.version_info[0:2] != (3, 11):
raise AssertionError(f'Unexpected python version {sys.version}')
if sys.platform == 'win32':
import py2exe # noqa: F401 # Yes, this *is* used
dist_dir = 'dist.win32'
else:
raise AssertionError(f'Unsupported platform {sys.platform}')
# This added to make mypy happy
assert sys.platform == 'win32'
###########################################################################
###########################################################################
# Retrieve current git short hash and store in file GITVERSION_FILE
###########################################################################
git_shorthash = git_shorthash_from_head()
if git_shorthash is None:
exit(-1)
with open(GITVERSION_FILE, 'w+', encoding='utf-8') as gvf:
gvf.write(git_shorthash)
print(f'Git short hash: {git_shorthash}')
###########################################################################
###########################################################################
# Misc. Configuration
###########################################################################
# Split version, as py2exe wants the 'base' for version
semver = appversion()
appversion_str = str(semver)
base_appversion = str(semver.truncate('patch'))
# Ensure a clean `dist_dir` by first removing it.
if dist_dir and len(dist_dir) > 1 and isdir(dist_dir):
shutil.rmtree(dist_dir)
# Windows paths
WIXPATH = r'C:\Program Files (x86)\WiX Toolset v3.11\bin'
SDKPATH = r'C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86'
###########################################################################
###########################################################################
###########################################################################
# Set up all the options, extra files etc. for py2exe build.
###########################################################################
APP = 'EDMarketConnector.py'
APPCMD = 'EDMC.py'
PLUGINS = [
'plugins/coriolis.py',
'plugins/eddn.py',
'plugins/edsm.py',
'plugins/edsy.py',
'plugins/inara.py',
]
OPTIONS = {
'py2exe': {
'dist_dir': dist_dir,
'optimize': 2,
'packages': [
'asyncio', # No longer auto as of py3.10+py2exe 0.11
'multiprocessing', # No longer auto as of py3.10+py2exe 0.11
'pkg_resources._vendor.platformdirs', # Necessary 2023-01-17
'sqlite3', # Included for plugins
'util', # 2022-02-01 only imported in plugins/eddn.py
],
'includes': [
'dataclasses',
'shutil', # Included for plugins
'timeout_session',
'zipfile', # Included for plugins
],
'excludes': [
'distutils',
'_markerlib',
'optparse',
'PIL',
'simplejson',
'unittest'
],
}
}
DATA_FILES = [
('', [
'.gitversion', # Contains git short hash
'WinSparkle.dll',
'WinSparkle.pdb', # For debugging - don't include in package
'EUROCAPS.TTF',
'ChangeLog.md',
'snd_good.wav',
'snd_bad.wav',
'modules.p',
'ships.p',
f'{appname}.VisualElementsManifest.xml',
f'{appname}.ico',
'EDMarketConnector - TRACE.bat',
'EDMarketConnector - localserver-auth.bat',
'EDMarketConnector - reset-ui.bat',
]),
('L10n', [join('L10n', x) for x in os.listdir('L10n') if x.endswith('.strings')]),
('FDevIDs', [
join('FDevIDs', 'commodity.csv'),
join('FDevIDs', 'rare_commodity.csv'),
]),
('plugins', PLUGINS),
]
###########################################################################
###########################################################################
# Use py2exe's `freeze()` to produce the executables.
###########################################################################
freeze(
version_info={
'description': 'Downloads commodity market and other station data from the game Elite Dangerous for use with'
' all popular online and offline trading tools.',
'company_name': 'EDCD', # Used by WinSparkle
'product_name': appname, # Used by WinSparkle
'version': base_appversion,
'product_version': appversion_str,
'copyright': copyright,
'language': 'English (United States)',
},
windows=[
{
'dest_base': appname,
'script': APP,
'icon_resources': [(0, f'{appname}.ico')],
'other_resources': [(24, 1, open(f'{appname}.manifest').read())],
}
],
console=[
{
'dest_base': appcmdname,
'script': APPCMD,
'other_resources': [(24, 1, open(f'{appcmdname}.manifest').read())],
}
],
data_files=DATA_FILES,
options=OPTIONS,
)
###########################################################################
###########################################################################
# Build installer(s)
###########################################################################
package_filename = None
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
os.system(rf'"{WIXPATH}\heat.exe" dir {dist_dir}\ -ag -sfrag -srid -suid -out {components_file}')
component_tree = etree.parse(str(components_file))
# 1. Change the element:
#
# <Directory Id="dist.win32" Name="dist.win32">
#
# to:
#
# <Directory Id="INSTALLDIR" Name="$(var.PRODUCTNAME)">
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)')
# 2. Change:
#
# <Component Id="EDMarketConnector.exe" Guid="*">
# <File Id="EDMarketConnector.exe" KeyPath="yes" Source="SourceDir\EDMarketConnector.exe" />
# </Component>
#
# to:
#
# <Component Id="MainExecutable" Guid="{D33BB66E-9664-4AB6-A044-3004B50A09B0}">
# <File Id="EDMarketConnector.exe" KeyPath="yes" Source="SourceDir\EDMarketConnector.exe" />
# <Shortcut Id="MainExeShortcut" Directory="ProgramMenuFolder" Name="$(var.PRODUCTLONGNAME)"
# Description="Downloads station data from Elite: Dangerous" WorkingDirectory="INSTALLDIR"
# Icon="EDMarketConnector.exe" IconIndex="0" Advertise="yes" />
# </Component>
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
)
os.system(rf'"{WIXPATH}\candle.exe" {appname}.wxs')
if not exists(f'{appname}.wixobj'):
raise AssertionError(f'No {appname}.wixobj: candle.exe failed?')
package_filename = f'{appname}_win_{appversion_nobuild()}.msi'
os.system(rf'"{WIXPATH}\light.exe" -b {dist_dir}\ -sacl -spdb -sw1076 {appname}.wixobj -out {package_filename}')
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
lcids = [
int(x) for x in re.search( # type: ignore
r'Languages\s*=\s*"(.+?)"',
open(f'{appname}.wxs').read()
).group(1).split(',')
]
assert lcids[0] == 1033, f'Default language is {lcids[0]}, should be 1033 (en_US)'
shutil.copyfile(package_filename, join(gettempdir(), f'{appname}_1033.msi'))
for lcid in lcids[1:]:
shutil.copyfile(
join(gettempdir(), f'{appname}_1033.msi'),
join(gettempdir(), f'{appname}_{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()}\{appname}_{lcid}.msi Product {lcid}')
os.system(rf'"{SDKPATH}\MsiTran.Exe" -g {gettempdir()}\{appname}_1033.msi {gettempdir()}\{appname}_{lcid}.msi {gettempdir()}\{lcid}.mst') # noqa: E501 # Not going to get shorter
os.system(rf'cscript /nologo "{SDKPATH}\WiSubStg.vbs" {package_filename} {gettempdir()}\{lcid}.mst {lcid}')
###########################################################################

View File

@ -389,7 +389,7 @@ information about this build process.
Thus, you **MUST** check if any imports you add in `plugins/*.py` files are only
referenced in that file (or also only in any other core plugin), and if so
**YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN `Build-exe-and-msi.py`
**YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN `build.py`
IN ORDER TO ENSURE THE FILES ARE ACTUALLY PRESENT IN AN END-USER
INSTALLATION ON WINDOWS.**
@ -409,7 +409,7 @@ the appropriate `packages` definition to:
Note that in this case it's in `packages` because we want the whole directory
adding. For a single file an extra item in `includes` would suffice.
Such additions to `Build-exe-and-msi.py` should not cause any issues if
Such additions to `build.py` should not cause any issues if
subsequent project changes cause `py2exe` to automatically pick up the same
file(s).

@ -1 +1 @@
Subproject commit 2aaf3cb023fc8c06e092efd0b81315c167f455f5
Subproject commit e8dbd99ddc00beabac140bf26f423a353bc98c5d

188
build.py Normal file
View File

@ -0,0 +1,188 @@
"""
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 shutil
import sys
import pathlib
from typing import List, Tuple
from string import Template
from os.path import join, isdir
import py2exe
from config import (
appcmdname,
appname,
appversion,
copyright,
git_shorthash_from_head,
_static_appversion,
)
def iss_build(template_path: str, output_file: str) -> None:
"""Build the .iss file needed for building the installer EXE."""
sub_vals = {"appver": _static_appversion}
with open(template_path, encoding="UTF8") as template_file:
src = Template(template_file.read())
newfile = src.substitute(sub_vals)
with open(output_file, "w", encoding="UTF8") as new_file:
new_file.write(newfile)
def system_check(dist_dir: str) -> str:
"""Check if the system is able to build."""
if sys.version_info < (3, 11):
sys.exit(f"Unexpected Python version {sys.version}")
if sys.platform != "win32":
sys.exit(f"Unsupported platform {sys.platform}")
git_shorthash = git_shorthash_from_head()
if git_shorthash is None:
sys.exit("Invalid Git Hash")
gitversion_file = ".gitversion"
with open(gitversion_file, "w+", encoding="utf-8") as gvf:
gvf.write(git_shorthash)
print(f"Git short hash: {git_shorthash}")
if dist_dir and len(dist_dir) > 1 and isdir(dist_dir):
shutil.rmtree(dist_dir)
return gitversion_file
def generate_data_files(
app_name: str, gitversion_file: str, plugins: List[str]
) -> List[Tuple[str, List[str]]]:
"""Create the required datafiles to build."""
l10n_dir = "L10n"
fdevids_dir = "FDevIDs"
data_files = [
(
"",
[
gitversion_file,
"WinSparkle.dll",
"WinSparkle.pdb",
"EUROCAPS.TTF",
"ChangeLog.md",
"snd_good.wav",
"snd_bad.wav",
"modules.p",
"ships.p",
f"{app_name}.VisualElementsManifest.xml",
f"{app_name}.ico",
"EDMarketConnector - TRACE.bat",
"EDMarketConnector - localserver-auth.bat",
"EDMarketConnector - reset-ui.bat",
],
),
(
l10n_dir,
[join(l10n_dir, x) for x in os.listdir(l10n_dir) if x.endswith(".strings")],
),
(
fdevids_dir,
[
join(fdevids_dir, "commodity.csv"),
join(fdevids_dir, "rare_commodity.csv"),
],
),
("plugins", plugins),
]
return data_files
def build() -> None:
"""Build EDMarketConnector using Py2Exe."""
dist_dir: str = "dist.win32"
gitversion_filename: str = system_check(dist_dir)
# Constants
plugins: List[str] = [
"plugins/coriolis.py",
"plugins/eddn.py",
"plugins/edsm.py",
"plugins/edsy.py",
"plugins/inara.py",
]
options: dict = {
"py2exe": {
"dist_dir": dist_dir,
"optimize": 2,
"packages": [
"asyncio",
"multiprocessing",
"pkg_resources._vendor.platformdirs",
"sqlite3",
"util",
],
"includes": ["dataclasses", "shutil", "timeout_session", "zipfile"],
"excludes": [
"distutils",
"_markerlib",
"optparse",
"PIL",
"simplejson",
"unittest",
"doctest",
"pdb",
"difflib",
],
}
}
# Function to generate DATA_FILES list
data_files: List[Tuple[str, List[str]]] = generate_data_files(
appname, gitversion_filename, plugins
)
version_info: dict = {
"description": "Downloads commodity market and other station data from the game"
" Elite Dangerous for use with all popular online and offline trading tools.",
"company_name": "EDCD", # Used by WinSparkle
"product_name": appname, # Used by WinSparkle
"version": str(appversion().truncate()),
"product_version": str(appversion()),
"copyright": copyright,
"language": "English (United States)",
}
windows_config: dict = {
"dest_base": appname,
"script": "EDMarketConnector.py",
"icon_resources": [(0, f"{appname}.ico")],
"other_resources": [
(24, 1, pathlib.Path(f"{appname}.manifest").read_text(encoding="UTF8"))
],
}
console_config: dict = {
"dest_base": appcmdname,
"script": "EDMC.py",
"other_resources": [
(24, 1, pathlib.Path(f"{appcmdname}.manifest").read_text(encoding="UTF8"))
],
}
py2exe.freeze(
version_info=version_info,
windows=[windows_config],
console=[console_config],
data_files=data_files,
options=options,
)
iss_template_path: str = "./resources/EDMC_Installer_Config_template.txt"
iss_file_path: str = "./EDMC_Installer_Config.iss"
# Build the ISS file
iss_build(iss_template_path, iss_file_path)
if __name__ == "__main__":
build()

View File

@ -52,7 +52,7 @@ appcmdname = 'EDMC'
# <https://semver.org/#semantic-versioning-specification-semver>
# Major.Minor.Patch(-prerelease)(+buildmetadata)
# NB: Do *not* import this, use the functions appversion() and appversion_nobuild()
_static_appversion = '5.9.0'
_static_appversion = '5.9.1-alpha0'
_cached_version: Optional[semantic_version.Version] = None
copyright = '© 2015-2019 Jonathan Harris, 2020-2023 EDCD'

@ -1 +1 @@
Subproject commit 566d768a711362c423748963c5f56d3bea68e6a5
Subproject commit 05b16a4c716980ea95a46d29205f7d3b1f957fb4

View File

@ -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 `<zip file>\<version>\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-exe-and-msi.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
@ -100,13 +97,13 @@ resulting .exe and/or .msi files. **But** realise that the resulting program
will still try to check for new versions at the main URL unless you change
that.
1. Company is set in `Build-exe-and-msi.py`. Search for `company_name`. This
1. Company is set in `build.py`. Search for `company_name`. This
is what appears in the EXE properties, and is also used as the location of
WinSparkle registry entries on Windows.
1. Application names, version and URL of the file with latest release
information. These are all in the `config/__init__.py` file. See the
`from config import ...` lines in `Build-exe-and-msi.py`:
`from config import ...` lines in `build.py`:
1. `appname`: The short appname, e.g. 'EDMarketConnector'
2. `applongname`: The long appname, e.g. 'E:D Market Connector'
3. `appcmdname`: The CLI appname, e.g. 'EDMC'
@ -144,48 +141,11 @@ that.
If you add a new file to the program that needs to be distributed to users as
well then you will need to properly add it to the build process.
### Build-exe-and-msi.py
### build.py
You'll need to add it in `Build-exe-and-msi.py` so that py2exe includes it in
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
<Directory Id="ProgramFilesFolder">
```
section and add a new sub-section:
```xml
<Component Id="<valid_component_id>" Guid=""*">
<File KeyPath="yes" Source="SourceDir\\<file name>" />
</Component>
```
Note that you only need `Id="<valid_component_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
<Feature Id='Complete' Level='1'>
```
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
<ComponentRef Id="<valid_component_id>" />
```
# Pre-Packaging Steps
Before you create a new install each time you should:
@ -260,19 +220,19 @@ a 'Git bash' window. The 'Terminal' tab of PyCharm works fine.
Assuming the correct python.exe is associated with .py files then simply run:
```batch
Build-exe-and-msi.py
build.py
```
else you might need this, which assumes correct python.exe is in your PATH:
```batch
python.exe Build-exe-and-msi.py
python.exe build.py
```
else you'll have to specify the path to python.exe, e.g.:
```batch
"C:\Program Files \(x86)\Python38-32\python.exe" Build-exe-and-msi.py
"C:\Program Files \(x86)\Python38-32\python.exe" build.py
```
Output will be something like (`...` denoting parts elided for brevity):
@ -284,31 +244,11 @@ 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
to be included in the install. If they're not picked up by current rules in
`Build-exe-and-msi.py` then you will need to add them to the `win32`
`build.py` then you will need to add them to the `win32`
`DATA_FILES` array.
You should now have one new/updated folder `dist.win32` and two new 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_installer_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:
@ -456,6 +393,6 @@ When changing the Python version (Major.Minor.Patch) used:
1. Major or Minor level changes:
1. `Build-exe-and-msi.py` will need its version check updating.
1. `build.py` will need its version check updating.
2. `.pre-commit-config.yaml` will need the `default_language_version`
section updated to the appropriate version.

View File

@ -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:
`<Directory Id="L10n" Name="L10n">`
section, e.g.:
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\sr-Latn-BA.strings" />
</Component>`
1. You also need to add a line in the:
<Feature Id='Complete' Level='1'>
section, e.g.:
<ComponentRef Id="sr_Latn_BA.strings" />
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.

View File

@ -6,7 +6,7 @@ this is to include an XML-format .manifest file at build time.
## Build time
We specify .manifest files in `Build-exe-and-msi.py`.
We specify .manifest files in `build.py`.
## Editing or changing a manifest

45
installer.py Normal file
View File

@ -0,0 +1,45 @@
"""
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
from build import build
def run_inno_setup_installer(iss_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_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 err:
print(
f"Error: Inno Setup compiler returned an error (exit code {err.returncode}):"
)
print(err.output.decode())
except Exception as err:
print(f"Error: An unexpected error occurred: {err}")
if __name__ == "__main__":
build()
# Add the ISS Template File
iss_file_path: str = "./EDMC_Installer_Config.iss"
# Build the ISS file
run_inno_setup_installer(iss_file_path)

View File

@ -16,7 +16,7 @@
# referenced in this file (or only in any other core plugin), and if so...
#
# YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN
# `Build-exe-and-msi.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT
# `build.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT
# IN AN END-USER INSTALLATION ON WINDOWS.
#
# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $#

View File

@ -16,7 +16,7 @@
# referenced in this file (or only in any other core plugin), and if so...
#
# YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN
# `Build-exe-and-msi.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT
# `build.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT
# IN AN END-USER INSTALLATION ON WINDOWS.
#
# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $#

View File

@ -25,7 +25,7 @@
# referenced in this file (or only in any other core plugin), and if so...
#
# YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN
# `Build-exe-and-msi.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT IN
# `build.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT IN
# AN END-USER INSTALLATION ON WINDOWS.
#
#

View File

@ -16,7 +16,7 @@
# referenced in this file (or only in any other core plugin), and if so...
#
# YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN
# `Build-exe-and-msi.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT IN
# `build.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT IN
# AN END-USER INSTALLATION ON WINDOWS.
#
#

View File

@ -16,7 +16,7 @@
# referenced in this file (or only in any other core plugin), and if so...
#
# YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN
# `Build-exe-and-msi.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT
# `build.py` SO AS TO ENSURE THE FILES ARE ACTUALLY PRESENT
# IN AN END-USER INSTALLATION ON WINDOWS.
#
# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $#

View File

@ -1,9 +1,6 @@
[tool.autopep8]
max_line_length = 120
[tool.isort]
multi_line_output = 5
line_length = 119
[tool.pytest.ini_options]
testpaths = ["tests"] # Search for tests in tests/

View File

@ -13,8 +13,6 @@ flake8-annotations-coverage==0.0.6
flake8-cognitive-complexity==0.1.0
flake8-comprehensions==3.14.0
flake8-docstrings==1.7.0
isort==5.12.0
flake8-isort==6.0.0
flake8-json==23.7.0
flake8-noqa==1.3.2
flake8-polyfill==1.0.2
@ -36,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:
# <https://github.com/py2exe/py2exe/issues/126>
py2exe==0.13.0.0; sys_platform == 'win32'
# Testing

View File

@ -0,0 +1,67 @@
#define MyAppName "EDMarketConnector"
#define MyAppVersion "$appver"
#define MyAppPublisher "EDCD"
#define MyAppURL "https://edcd.github.io/"
#define SuppURL "https://github.com/EDCD/EDMarketConnector/"
#define MyAppExeName "EDMarketConnector.exe"
[Setup]
AppId={{5E9AD4D3-0365-41D5-9586-9368745DD109}
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
OutputBaseFilename=EDMarketConnector_Installer_{#MyAppVersion}
SetupIconFile=dist.win32\EDMarketConnector.ico
Compression=lzma2/max
SolidCompression=yes
WizardStyle=modern
InfoBeforeFile=dist.win32\Changelog.md
OutputDir=.
LicenseFile=LICENSE
AlwaysShowDirOnReadyPage=yes
UninstallDisplayIcon={app}\{#MyAppExeName}
[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
[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
;Check if a WiX-based installation exists. If so, kill it with fire.
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
ResultCode: Integer;
Uninstall: String;
begin
if (CurStep = ssInstall) then begin
if RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{5E9AD4D3-0365-41D5-9586-9368745DD109}', 'UninstallString', Uninstall) then begin
MsgBox('Warning: an old version of EDMC is installed! Please close EDMC while we remove the old version!', mbInformation, MB_OK);
Uninstall := '/x {5E9AD4D3-0365-41D5-9586-9368745DD109}';
Exec('MsiExec.exe', Uninstall, '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
end;
end;

View File

@ -1,720 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<?define PRODUCTNAME = "EDMarketConnector"?>
<?define PRODUCTLONGNAME = "Elite Dangerous Market Connector"?>
<?define PRODUCTVERSION = "!(bind.fileVersion.EDMarketConnector.exe)" ?>
<?define UPGRADECODE = "9df571ae-d56d-46e6-af79-4e72ad54efe6" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="$(var.PRODUCTLONGNAME)"
Version="$(var.PRODUCTVERSION)"
UpgradeCode="$(var.UPGRADECODE)"
Language="!(bind.fileLanguage.EDMarketConnector.exe)"
Manufacturer="EDCD">
<Package Id="*" Keywords="Installer"
InstallScope="perMachine"
Description="$(var.PRODUCTLONGNAME) installer"
InstallerVersion="300" Compressed="yes"
Platform="x86"
Languages="1033,1029,1031,1034,1035,1036,1038,1040,1041,1043,1045,1046,1049,1058,1062,2052,2070,2074,6170,1060,1053,18,0" />
<!-- en cs, de es fi fr hu it ja nl pl pt-BR ru uk lv zh-CN pt-PT sr-Latn sr-Latn-BA sl sv-SE ko neutral -->
<!-- https://msdn.microsoft.com/en-gb/goglobal/bb964664.aspx -->
<!-- Always reinstall since patching is problematic -->
<!-- http://www.joyofsetup.com/2010/01/16/major-upgrades-now-easier-than-ever/ -->
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<Icon Id="EDMarketConnector.exe" SourceFile="EDMarketConnector.ico"/>
<!-- For Add/Remove programs -->
<Property Id="ARPPRODUCTICON" Value="EDMarketConnector.exe" />
<Property Id="ARPNOMODIFY" Value="yes" Secure="yes" /> <!-- Remove modify - also set by WixUI_Minimal -->
<Property Id="ARPHELPLINK" Value="https://github.com/EDCD/EDMarketConnector/wiki" />
<!-- Set INSTALLDIR from ARPINSTALLLOCATION if replacing/upgrading -->
<!-- https://wyrdfish.wordpress.com/2012/07/20/msi-writing-guidelines-this-may-be-out-of-date/ -->
<Property Id="ARPINSTALLLOCATION">
<RegistrySearch Id="GetARPINSTALLLOCATION"
Root="HKLM"
Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[WIX_UPGRADE_DETECTED]"
Name="InstallLocation"
Type="raw" />
</Property>
<CustomAction Id="SetINSTALLDIR" Property="INSTALLDIR" Value="[ARPINSTALLLOCATION]" />
<InstallUISequence>
<Custom Action="SetINSTALLDIR" After="AppSearch">
WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION
</Custom>
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="SetINSTALLDIR" After="AppSearch">
WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION
</Custom>
</InstallExecuteSequence>
<!-- Set ARPINSTALLLOCATION from INSTALLDIR if new install -->
<!-- http://blogs.technet.com/b/alexshev/archive/2008/02/09/from-msi-to-wix-part-2.aspx -->
<CustomAction Id="SetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
<InstallExecuteSequence>
<Custom Action="SetARPINSTALLLOCATION" After="InstallValidate">
NOT Installed
</Custom>
</InstallExecuteSequence>
<!-- Launch app after upgrade -->
<Property Id="LAUNCH" Value="yes" />
<CustomAction Id="DoLaunch"
Directory="INSTALLDIR"
ExeCommand='"[INSTALLDIR]EDMarketConnector.exe"'
Return="asyncNoWait"
Execute="deferred"
Impersonate="yes"
/>
<InstallExecuteSequence>
<!-- http://alekdavis.blogspot.co.uk/2013/05/wix-woes-what-is-your-installer-doing.html -->
<Custom Action="DoLaunch" Before="InstallFinalize">
NOT Installed AND LAUNCH ~= "yes"
</Custom>
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<!-- http://wixtoolset.org/documentation/manual/v3/howtos/files_and_registry/write_a_registry_entry.html -->
<Component Id="RegistryEntries" Guid="*">
<RegistryKey Root="HKCR" Key="edmc">
<RegistryValue Type="string" Value="$(var.PRODUCTLONGNAME)"/>
<RegistryValue Type="string" Name="URL Protocol" Value=""/>
<RegistryKey Key="DefaultIcon">
<RegistryValue Type="string" Value="[INSTALLDIR]EDMarketConnector.exe,0"/>
</RegistryKey>
<RegistryKey Key="shell">
<RegistryKey Key="open">
<RegistryKey Key="command">
<RegistryValue Type="string" Value='"[INSTALLDIR]EDMarketConnector.exe" "%1"'/>
</RegistryKey>
<RegistryKey Key="ddeexec">
<RegistryValue Type="string" Value='Open("%1")'/>
</RegistryKey>
</RegistryKey>
</RegistryKey>
</RegistryKey>
</Component>
<!-- Generate with `heat.exe dir dist.win32 -ag -sfrag -suid -out foo.wxs` -->
<!-- Sadly too late for auto-generated Component UUIDs -->
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="$(var.PRODUCTNAME)">
<Component Id="MainExecutable" Guid="{D33BB66E-9664-4AB6-A044-3004B50A09B0}">
<File Id="EDMarketConnector.exe" KeyPath="yes" Source="SourceDir\EDMarketConnector.exe" />
<Shortcut Id="MainExeShortcut" Directory="ProgramMenuFolder" Name="$(var.PRODUCTLONGNAME)" Description="Downloads station data from Elite: Dangerous" WorkingDirectory="INSTALLDIR" Icon="EDMarketConnector.exe" IconIndex="0" Advertise="yes" />
</Component>
<Component Guid="{842DC919-EC3D-48EF-A6B3-9A81608E0FB9}">
<File KeyPath="yes" Source="SourceDir\_bz2.pyd" />
</Component>
<Component Guid="{433C38E1-F736-4546-AA83-FCD8B0AAA39B}">
<File KeyPath="yes" Source="SourceDir\_ctypes.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\_decimal.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\_elementtree.pyd" />
</Component>
<Component Guid="{45803711-A2A6-4DA8-8219-F625DE6DB33E}">
<File KeyPath="yes" Source="SourceDir\_hashlib.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\_lzma.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\_queue.pyd" />
</Component>
<Component Guid="{52019FB5-952D-4BA4-A6E0-F3E214F14923}">
<File KeyPath="yes" Source="SourceDir\_socket.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\_sqlite3.pyd" />
</Component>
<Component Guid="{2EA8F0B6-A104-4D31-99F0-3535ACDC26A9}">
<File KeyPath="yes" Source="SourceDir\_ssl.pyd" />
</Component>
<Component Guid="{D2F0CDD2-E934-419F-BC99-445E8FD3AF24}">
<File KeyPath="yes" Source="SourceDir\_tkinter.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\_uuid.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\_win32sysloader.pyd" />
</Component>
<Component Guid="{62DF41B7-0BE8-48F3-BB22-90E9201A6D8C}">
<File KeyPath="yes" Source="SourceDir\cacert.pem" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\ChangeLog.md" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\commodity.csv" />
</Component>
<Component Guid="{6762E871-5FA1-4C2F-A3C9-6A9954CC018C}">
<File KeyPath="yes" Source="SourceDir\EDMarketConnector.ico" />
</Component>
<Component Guid="{9A0CB8A2-7167-492F-A185-0BDF7E9F5C01}">
<File KeyPath="yes" Source="SourceDir\EDMarketConnector.VisualElementsManifest.xml" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\EDMC.exe" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\EUROCAPS.TTF" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\libcrypto-1_1.dll" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\libffi-7.dll" />
</Component>
<Component Guid="{A18814B6-B491-42AB-A433-2AD66A823AD7}">
<File KeyPath="yes" Source="SourceDir\library.zip" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\libssl-1_1.dll" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\modules.p" />
</Component>
<Component Guid="{87A99AAA-792F-4092-9D00-5106D99D00AD}">
<File KeyPath="yes" Source="SourceDir\pyexpat.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\python310.dll" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\pythoncom310.dll" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\pywintypes310.dll" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\rare_commodity.csv" />
</Component>
<Component Guid="{9DBAB544-E815-40A5-866A-391B68919344}">
<File KeyPath="yes" Source="SourceDir\select.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\ships.p" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\snd_good.wav" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\snd_bad.wav" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\sqlite3.dll" />
</Component>
<Component Guid="{30EEAD30-A43B-4A31-A209-450A8AD17AC2}">
<File KeyPath="yes" Source="SourceDir\tcl86t.dll" />
</Component>
<Component Guid="{CE5A6F3A-8F6B-4C16-BCDC-F1BB89C9F1AF}">
<File KeyPath="yes" Source="SourceDir\tk86t.dll" />
</Component>
<Component Guid="{E8E3701A-8AA1-4D46-A56D-7AF08D6AFCD4}">
<File KeyPath="yes" Source="SourceDir\unicodedata.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\win32api.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\win32com.shell.shell.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\win32evtlog.pyd" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\winsound.pyd" />
</Component>
<Component Guid="{3117D2CF-1D87-4B99-BE44-7BDDFE8C8E60}">
<File KeyPath="yes" Source="SourceDir\WinSparkle.dll" />
</Component>
<Component Id="EDMarketConnector_TRACE.bat" Guid="*">
<File KeyPath="yes" Source="SourceDir\EDMarketConnector - TRACE.bat" />
</Component>
<Component Id="EDMarketConnector_localserver_auth.bat" Guid="*">
<File KeyPath="yes" Source="SourceDir\EDMarketConnector - localserver-auth.bat" />
</Component>
<Component Id="EDMarketConnector_localserver_resetui.bat" Guid="*">
<File KeyPath="yes" Source="SourceDir\EDMarketConnector - reset-ui.bat" />
</Component>
<Component Id="gitversion" Guid="*">
<File KeyPath="yes" Source="SourceDir\.gitversion" />
</Component>
<Directory Id="L10n" Name="L10n">
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\cs.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\de.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\es.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\fi.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\fr.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\hu.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\it.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\ja.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\ko.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\lv.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\nl.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\pl.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\pt-BR.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\pt-PT.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\ru.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\sl.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\sr-Latn.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\sr-Latn-BA.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\sv-SE.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\uk.strings" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\L10n\zh-Hans.strings" Name="zh-CN.strings" />
</Component>
</Directory>
<Directory Id="lib" Name="lib">
<Directory Id="tcl" Name="tcl">
<Component Guid="{C085794D-6644-4915-B1C3-3060BE9E3F3B}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\auto.tcl" />
</Component>
<Component Guid="{E7EF4423-9B28-4267-A6C9-1C5F5F732054}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\clock.tcl" />
</Component>
<Component Guid="{28C0596D-8D38-4E62-BE6E-E3986E1EB854}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\history.tcl" />
</Component>
<Component Guid="{3E20540F-0017-40FA-94EC-A4407C0A9B3B}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\init.tcl" />
</Component>
<Component Guid="{D3750297-0753-433F-A20F-FCB309050DCE}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\package.tcl" />
</Component>
<Component Guid="{8686095A-7B3D-4352-B30C-497E3DAABD57}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\parray.tcl" />
</Component>
<Component Guid="{DAAAF7FC-8255-4564-B4F9-42865C1D1B74}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\safe.tcl" />
</Component>
<Component Id="tclIndex_1" Guid="{52C48E34-AE8C-4461-BB3D-817EF66E859A}">
<File Id="tclIndex_1" KeyPath="yes" Source="SourceDir\lib\tcl\tclIndex" />
</Component>
<Component Guid="{84CAEEAD-0290-4895-BEDB-6CB10B8BEECE}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\tm.tcl" />
</Component>
<Component Guid="{3D7917B8-E131-448F-9F2C-18705BB37313}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\word.tcl" />
</Component>
<Directory Id="opt0.4" Name="opt0.4">
<Component Guid="{D8E99FE8-AD1E-4E73-A566-6D88B7E5F07E}">
<File KeyPath="yes" Source="SourceDir\lib\tcl\opt0.4\optparse.tcl" />
</Component>
<Component Id="pkgIndex.tcl_1" Guid="{9618212A-46A6-4982-AB85-599CEB0711EB}">
<File Id="pkgIndex.tcl_1" KeyPath="yes" Source="SourceDir\lib\tcl\opt0.4\pkgIndex.tcl" />
</Component>
</Directory>
</Directory>
<Directory Id="tk" Name="tk">
<Component Guid="{FCB37425-AD3A-45DA-91D7-053AF7970C28}">
<File KeyPath="yes" Source="SourceDir\lib\tk\bgerror.tcl" />
</Component>
<Component Id="button.tcl_1" Guid="{149136E1-0EAE-42B2-8509-5B6A686B023B}">
<File Id="button.tcl_1" KeyPath="yes" Source="SourceDir\lib\tk\button.tcl" />
</Component>
<Component Guid="{EAC4BD6C-40E9-4C64-A5F5-258D083D07C0}">
<File KeyPath="yes" Source="SourceDir\lib\tk\choosedir.tcl" />
</Component>
<Component Guid="{0E8924C5-7EA5-43AC-9C81-6F3029B462C8}">
<File KeyPath="yes" Source="SourceDir\lib\tk\clrpick.tcl" />
</Component>
<Component Guid="{7B5F5CA4-893A-480F-B6AF-C3E3A544DB8B}">
<File KeyPath="yes" Source="SourceDir\lib\tk\comdlg.tcl" />
</Component>
<Component Guid="{A8F00EE2-4094-4DFF-86BD-FE969D4D362A}">
<File KeyPath="yes" Source="SourceDir\lib\tk\console.tcl" />
</Component>
<Component Guid="{DFFA82C4-0949-41A3-868A-1BC4CF04CC76}">
<File KeyPath="yes" Source="SourceDir\lib\tk\dialog.tcl" />
</Component>
<Component Id="entry.tcl_1" Guid="{D3BD7C0B-06D7-4619-977B-F30908EF20ED}">
<File Id="entry.tcl_1" KeyPath="yes" Source="SourceDir\lib\tk\entry.tcl" />
</Component>
<Component Guid="{DF8A00BF-91F1-44D8-B1D4-AB1104BFD1C9}">
<File KeyPath="yes" Source="SourceDir\lib\tk\focus.tcl" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\lib\tk\fontchooser.tcl" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\lib\tk\iconlist.tcl" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\lib\tk\icons.tcl" />
</Component>
<Component Guid="{A545EB30-9E1A-4C89-866B-974C99004065}">
<File KeyPath="yes" Source="SourceDir\lib\tk\license.terms" />
</Component>
<Component Guid="{A8F779C3-8947-4C8D-9611-83F1D05482A7}">
<File KeyPath="yes" Source="SourceDir\lib\tk\listbox.tcl" />
</Component>
<Component Guid="{E492B863-5AAA-4A2A-AC0B-10F2B3A90D89}">
<File KeyPath="yes" Source="SourceDir\lib\tk\menu.tcl" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\lib\tk\megawidget.tcl" />
</Component>
<Component Guid="{9BBAC909-602C-443B-9EFE-6896D468BE3F}">
<File KeyPath="yes" Source="SourceDir\lib\tk\mkpsenc.tcl" />
</Component>
<Component Guid="{0F1A63FD-16BA-4603-8E9D-744BC4CD5C25}">
<File KeyPath="yes" Source="SourceDir\lib\tk\msgbox.tcl" />
</Component>
<Component Guid="{4EDE9077-0998-42D9-8510-E60440003628}">
<File KeyPath="yes" Source="SourceDir\lib\tk\obsolete.tcl" />
</Component>
<Component Guid="{10D09DFC-4B7D-4869-ACBC-53C864C54CD0}">
<File KeyPath="yes" Source="SourceDir\lib\tk\optMenu.tcl" />
</Component>
<Component Guid="{EA101ACF-9743-495F-B514-A28F78F23068}">
<File KeyPath="yes" Source="SourceDir\lib\tk\palette.tcl" />
</Component>
<Component Id="panedwindow.tcl_1" Guid="{7060F5A9-BAB5-4D15-A65E-04A71AE00A15}">
<File Id="panedwindow.tcl_1" KeyPath="yes" Source="SourceDir\lib\tk\panedwindow.tcl" />
</Component>
<Component Id="pkgIndex.tcl_2" Guid="{5E2762E6-F8DE-43A9-A809-32AE03522482}">
<File Id="pkgIndex.tcl_2" KeyPath="yes" Source="SourceDir\lib\tk\pkgIndex.tcl" />
</Component>
<Component Guid="{DE3DA121-B02A-43AA-9D36-99A89F26B3B4}">
<File KeyPath="yes" Source="SourceDir\lib\tk\safetk.tcl" />
</Component>
<Component Id="scale.tcl_1" Guid="{7E371EB8-CBE1-4360-A1B8-08A54DEEFAE5}">
<File Id="scale.tcl_1" KeyPath="yes" Source="SourceDir\lib\tk\scale.tcl" />
</Component>
<Component Guid="{AADDC754-698D-4439-82A1-4F47FE97FA94}">
<File KeyPath="yes" Source="SourceDir\lib\tk\scrlbar.tcl" />
</Component>
<Component Id="spinbox.tcl_1" Guid="{448FB04F-1719-4BE0-8192-9DB3551FF1CA}">
<File Id="spinbox.tcl_1" KeyPath="yes" Source="SourceDir\lib\tk\spinbox.tcl" />
</Component>
<Component Id="tclIndex_2" Guid="{CC6A73B5-7CBF-43F5-BA1D-67216081B7CD}">
<File Id="tclIndex_2" KeyPath="yes" Source="SourceDir\lib\tk\tclIndex" />
</Component>
<Component Guid="{AEAAB0BF-64DA-4729-8AA3-A964758524F2}">
<File KeyPath="yes" Source="SourceDir\lib\tk\tearoff.tcl" />
</Component>
<Component Guid="{DFCA1825-61D8-4613-A0DF-7FAFC9E8D0B7}">
<File KeyPath="yes" Source="SourceDir\lib\tk\text.tcl" />
</Component>
<Component Guid="{80245D25-A889-4EB2-9C9C-488AB3C32A32}">
<File KeyPath="yes" Source="SourceDir\lib\tk\tk.tcl" />
</Component>
<Component Guid="{50929058-A5C7-43E3-B5FE-B848A419CF93}">
<File KeyPath="yes" Source="SourceDir\lib\tk\tkfbox.tcl" />
</Component>
<Component Guid="{2B892993-9862-466F-A79B-F54246A9E7F2}">
<File KeyPath="yes" Source="SourceDir\lib\tk\unsupported.tcl" />
</Component>
<Component Guid="{F7B0AE86-0EA3-436D-83A0-61FB4AEBBDF8}">
<File KeyPath="yes" Source="SourceDir\lib\tk\xmfbox.tcl" />
</Component>
<Directory Id="ttk" Name="ttk">
<Component Guid="{153EA00B-70D3-45D5-B6C7-F900D15AF3C7}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\altTheme.tcl" />
</Component>
<Component Guid="{F97CA810-C233-4088-87FB-5DE062166893}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\aquaTheme.tcl" />
</Component>
<Component Id="button.tcl_2" Guid="{2C2F700C-7C62-4F5A-908C-A35B122A577B}">
<File Id="button.tcl_2" KeyPath="yes" Source="SourceDir\lib\tk\ttk\button.tcl" />
</Component>
<Component Guid="{9137EAD5-A5ED-4280-AB41-5B42CB76BE25}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\clamTheme.tcl" />
</Component>
<Component Guid="{B9D2363E-CBE6-4D6A-8AEC-8763FCF41309}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\classicTheme.tcl" />
</Component>
<Component Guid="{BB9DC352-388A-4424-B3A7-D0CC0799B0E8}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\combobox.tcl" />
</Component>
<Component Guid="{D5B1A052-87F1-44C9-A8D6-6FF78EC6453A}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\cursors.tcl" />
</Component>
<Component Guid="{2D4A6C0F-16CC-458F-936E-68F39BB51DC5}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\defaults.tcl" />
</Component>
<Component Id="entry.tcl_2" Guid="{5BBDDCE5-3165-431C-8A5F-88C090EB98DA}">
<File Id="entry.tcl_2" KeyPath="yes" Source="SourceDir\lib\tk\ttk\entry.tcl" />
</Component>
<Component Guid="{D0DACDE6-4F3A-4BC2-AE09-7BBF8C76ED74}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\fonts.tcl" />
</Component>
<Component Guid="{133F83FA-ACE2-44FF-B175-42F2E0A917A9}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\menubutton.tcl" />
</Component>
<Component Guid="{641B8DCD-E718-4757-84AB-6425D3CFDCD6}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\notebook.tcl" />
</Component>
<Component Id="panedwindow.tcl_2" Guid="{AF0A3619-F409-479B-A71E-1D2C08A5F510}">
<File Id="panedwindow.tcl_2" KeyPath="yes" Source="SourceDir\lib\tk\ttk\panedwindow.tcl" />
</Component>
<Component Guid="{3E9DE75A-FD32-4F7E-A3E7-59ABFBCBC9DF}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\progress.tcl" />
</Component>
<Component Id="scale.tcl_2" Guid="{165FED9E-A3F0-4005-8DA8-D25E4E144DD8}">
<File Id="scale.tcl_2" KeyPath="yes" Source="SourceDir\lib\tk\ttk\scale.tcl" />
</Component>
<Component Guid="{735AFCC5-A597-4292-B144-4DF8865B4200}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\scrollbar.tcl" />
</Component>
<Component Guid="{54AD42EB-7305-45AA-953C-574921E90BAD}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\sizegrip.tcl" />
</Component>
<Component Id="spinbox.tcl_2" Guid="{F4A91FAD-5F8D-4007-B38E-2C706E87770B}">
<File Id="spinbox.tcl_2" KeyPath="yes" Source="SourceDir\lib\tk\ttk\spinbox.tcl" />
</Component>
<Component Guid="{FC12F75C-6EF1-4AD5-BF60-55FC5E825605}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\treeview.tcl" />
</Component>
<Component Guid="{947E3D83-15D1-44E5-B8D3-5EEBDD18B343}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\ttk.tcl" />
</Component>
<Component Guid="{D5534AC6-9A1B-4CE3-90E1-6B65D4FF86D6}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\utils.tcl" />
</Component>
<Component Guid="{198ADB32-56DD-4F29-B862-817DD6E92ECA}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\vistaTheme.tcl" />
</Component>
<Component Guid="{92589FA4-E08B-4E45-856E-F266D6290E2A}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\winTheme.tcl" />
</Component>
<Component Guid="{78CB3D2B-5032-445B-82C5-CFD32584A238}">
<File KeyPath="yes" Source="SourceDir\lib\tk\ttk\xpTheme.tcl" />
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="plugins" Name="plugins">
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\plugins\coriolis.py" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\plugins\eddn.py" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\plugins\edsm.py" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\plugins\edsy.py" />
</Component>
<Component Guid="*">
<File KeyPath="yes" Source="SourceDir\plugins\inara.py" />
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
</Directory>
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id="RegistryEntries" />
<ComponentRef Id="MainExecutable" />
<ComponentRef Id="gitversion" />
<ComponentRef Id="_bz2.pyd" />
<ComponentRef Id="_ctypes.pyd" />
<ComponentRef Id="_decimal.pyd" />
<ComponentRef Id="_elementtree.pyd" />
<ComponentRef Id="_hashlib.pyd" />
<ComponentRef Id="_lzma.pyd" />
<ComponentRef Id="_queue.pyd" />
<ComponentRef Id="_socket.pyd" />
<ComponentRef Id="_sqlite3.pyd" />
<ComponentRef Id="_ssl.pyd" />
<ComponentRef Id="_tkinter.pyd" />
<ComponentRef Id="_uuid.pyd" />
<ComponentRef Id="_win32sysloader.pyd" />
<ComponentRef Id="cacert.pem" />
<ComponentRef Id="ChangeLog.md" />
<ComponentRef Id="commodity.csv" />
<ComponentRef Id="cs.strings" />
<ComponentRef Id="de.strings" />
<ComponentRef Id="EDMarketConnector.ico" />
<ComponentRef Id="EDMarketConnector.VisualElementsManifest.xml" />
<ComponentRef Id="EDMC.exe" />
<ComponentRef Id="EUROCAPS.TTF" />
<ComponentRef Id="es.strings" />
<ComponentRef Id="fi.strings" />
<ComponentRef Id="fr.strings" />
<ComponentRef Id="hu.strings" />
<ComponentRef Id="it.strings" />
<ComponentRef Id="ja.strings" />
<ComponentRef Id="ko.strings" />
<ComponentRef Id="libcrypto_1_1.dll" />
<ComponentRef Id="libffi_7.dll" />
<ComponentRef Id="library.zip" />
<ComponentRef Id="libssl_1_1.dll" />
<ComponentRef Id="modules.p" />
<ComponentRef Id="lv.strings" />
<ComponentRef Id="nl.strings" />
<ComponentRef Id="pl.strings" />
<ComponentRef Id="pt_BR.strings" />
<ComponentRef Id="pt_PT.strings" />
<ComponentRef Id="pyexpat.pyd" />
<ComponentRef Id="python310.dll" />
<ComponentRef Id="pythoncom310.dll" />
<ComponentRef Id="pywintypes310.dll" />
<ComponentRef Id="rare_commodity.csv" />
<ComponentRef Id="ru.strings" />
<ComponentRef Id="select.pyd" />
<ComponentRef Id="ships.p" />
<ComponentRef Id="sl.strings" />
<ComponentRef Id="sr_Latn.strings" />
<ComponentRef Id="sr_Latn_BA.strings" />
<ComponentRef Id="snd_good.wav" />
<ComponentRef Id="snd_bad.wav" />
<ComponentRef Id="sqlite3.dll" />
<ComponentRef Id="sv_SE.strings" />
<ComponentRef Id="tcl86t.dll" />
<ComponentRef Id="tk86t.dll" />
<ComponentRef Id="uk.strings" />
<ComponentRef Id="unicodedata.pyd" />
<ComponentRef Id="win32api.pyd" />
<ComponentRef Id="win32com.shell.shell.pyd" />
<ComponentRef Id="win32evtlog.pyd" />
<ComponentRef Id="winsound.pyd" />
<ComponentRef Id="WinSparkle.dll" />
<ComponentRef Id="EDMarketConnector_TRACE.bat" />
<ComponentRef Id="EDMarketConnector_localserver_auth.bat" />
<ComponentRef Id="EDMarketConnector_localserver_resetui.bat" />
<ComponentRef Id="zh_CN.strings" />
<ComponentRef Id="auto.tcl" />
<ComponentRef Id="clock.tcl" />
<ComponentRef Id="history.tcl" />
<ComponentRef Id="init.tcl" />
<ComponentRef Id="package.tcl" />
<ComponentRef Id="parray.tcl" />
<ComponentRef Id="safe.tcl" />
<ComponentRef Id="tclIndex_1" />
<ComponentRef Id="tm.tcl" />
<ComponentRef Id="word.tcl" />
<ComponentRef Id="optparse.tcl" />
<ComponentRef Id="pkgIndex.tcl_1" />
<ComponentRef Id="bgerror.tcl" />
<ComponentRef Id="button.tcl_1" />
<ComponentRef Id="choosedir.tcl" />
<ComponentRef Id="clrpick.tcl" />
<ComponentRef Id="comdlg.tcl" />
<ComponentRef Id="console.tcl" />
<ComponentRef Id="dialog.tcl" />
<ComponentRef Id="entry.tcl_1" />
<ComponentRef Id="focus.tcl" />
<ComponentRef Id="fontchooser.tcl" />
<ComponentRef Id="iconlist.tcl" />
<ComponentRef Id="icons.tcl" />
<ComponentRef Id="license.terms" />
<ComponentRef Id="listbox.tcl" />
<ComponentRef Id="megawidget.tcl" />
<ComponentRef Id="menu.tcl" />
<ComponentRef Id="mkpsenc.tcl" />
<ComponentRef Id="msgbox.tcl" />
<ComponentRef Id="obsolete.tcl" />
<ComponentRef Id="optMenu.tcl" />
<ComponentRef Id="palette.tcl" />
<ComponentRef Id="panedwindow.tcl_1" />
<ComponentRef Id="pkgIndex.tcl_2" />
<ComponentRef Id="safetk.tcl" />
<ComponentRef Id="scale.tcl_1" />
<ComponentRef Id="scrlbar.tcl" />
<ComponentRef Id="spinbox.tcl_1" />
<ComponentRef Id="tclIndex_2" />
<ComponentRef Id="tearoff.tcl" />
<ComponentRef Id="text.tcl" />
<ComponentRef Id="tk.tcl" />
<ComponentRef Id="tkfbox.tcl" />
<ComponentRef Id="unsupported.tcl" />
<ComponentRef Id="xmfbox.tcl" />
<ComponentRef Id="altTheme.tcl" />
<ComponentRef Id="aquaTheme.tcl" />
<ComponentRef Id="button.tcl_2" />
<ComponentRef Id="clamTheme.tcl" />
<ComponentRef Id="classicTheme.tcl" />
<ComponentRef Id="combobox.tcl" />
<ComponentRef Id="cursors.tcl" />
<ComponentRef Id="defaults.tcl" />
<ComponentRef Id="entry.tcl_2" />
<ComponentRef Id="fonts.tcl" />
<ComponentRef Id="menubutton.tcl" />
<ComponentRef Id="notebook.tcl" />
<ComponentRef Id="panedwindow.tcl_2" />
<ComponentRef Id="progress.tcl" />
<ComponentRef Id="scale.tcl_2" />
<ComponentRef Id="scrollbar.tcl" />
<ComponentRef Id="sizegrip.tcl" />
<ComponentRef Id="spinbox.tcl_2" />
<ComponentRef Id="treeview.tcl" />
<ComponentRef Id="ttk.tcl" />
<ComponentRef Id="utils.tcl" />
<ComponentRef Id="vistaTheme.tcl" />
<ComponentRef Id="winTheme.tcl" />
<ComponentRef Id="xpTheme.tcl" />
<ComponentRef Id="coriolis.py" />
<ComponentRef Id="eddn.py" />
<ComponentRef Id="edsm.py" />
<ComponentRef Id="edsy.py" />
<ComponentRef Id="inara.py" />
</Feature>
</Product>
</Wix>
<!-- Local Variables: -->
<!-- tab-width: 4 -->
<!-- End: -->

View File

@ -1,130 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<?define PRODUCTNAME = "EDMarketConnector"?>
<?define PRODUCTLONGNAME = "Elite Dangerous Market Connector"?>
<?define PRODUCTVERSION = "!(bind.fileVersion.EDMarketConnector.exe)" ?>
<?define UPGRADECODE = "9df571ae-d56d-46e6-af79-4e72ad54efe6" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="$(var.PRODUCTLONGNAME)"
Version="$(var.PRODUCTVERSION)"
UpgradeCode="$(var.UPGRADECODE)"
Language="!(bind.fileLanguage.EDMarketConnector.exe)"
Manufacturer="EDCD">
<Package Id="*" Keywords="Installer"
InstallScope="perMachine"
Description="$(var.PRODUCTLONGNAME) installer"
InstallerVersion="300" Compressed="yes"
Platform="x86"
Languages="1033,1029,1031,1034,1035,1036,1038,1040,1041,1043,1045,1046,1049,1058,1062,2052,2070,2074,6170,1060,1053,18,0" />
<!-- en cs, de es fi fr hu it ja nl pl pt-BR ru uk lv zh-CN pt-PT sr-Latn sr-Latn-BA sl sv-SE ko neutral -->
<!-- https://msdn.microsoft.com/en-gb/goglobal/bb964664.aspx -->
<!-- Always reinstall since patching is problematic -->
<!-- http://www.joyofsetup.com/2010/01/16/major-upgrades-now-easier-than-ever/ -->
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<Icon Id="EDMarketConnector.exe" SourceFile="EDMarketConnector.ico"/>
<!-- For Add/Remove programs -->
<Property Id="ARPPRODUCTICON" Value="EDMarketConnector.exe" />
<Property Id="ARPNOMODIFY" Value="yes" Secure="yes" /> <!-- Remove modify - also set by WixUI_Minimal -->
<Property Id="ARPHELPLINK" Value="https://github.com/EDCD/EDMarketConnector/wiki" />
<!-- Set INSTALLDIR from ARPINSTALLLOCATION if replacing/upgrading -->
<!-- https://wyrdfish.wordpress.com/2012/07/20/msi-writing-guidelines-this-may-be-out-of-date/ -->
<Property Id="ARPINSTALLLOCATION">
<RegistrySearch Id="GetARPINSTALLLOCATION"
Root="HKLM"
Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[WIX_UPGRADE_DETECTED]"
Name="InstallLocation"
Type="raw" />
</Property>
<!-- Attempt to **NEVER** cause a reboot, e.g. if EDMarketConnector.exe
doesn't exit, and thus the installer can't properly replace it. -->
<Property Id="REBOOT" Value="ReallySuppress" />
<CustomAction Id="SetINSTALLDIR" Property="INSTALLDIR" Value="[ARPINSTALLLOCATION]" />
<InstallUISequence>
<Custom Action="SetINSTALLDIR" After="AppSearch">
WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION
</Custom>
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="SetINSTALLDIR" After="AppSearch">
WIX_UPGRADE_DETECTED AND ARPINSTALLLOCATION
</Custom>
</InstallExecuteSequence>
<!-- Set ARPINSTALLLOCATION from INSTALLDIR if new install -->
<!-- http://blogs.technet.com/b/alexshev/archive/2008/02/09/from-msi-to-wix-part-2.aspx -->
<CustomAction Id="SetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
<InstallExecuteSequence>
<Custom Action="SetARPINSTALLLOCATION" After="InstallValidate">
NOT Installed
</Custom>
</InstallExecuteSequence>
<!-- Launch app after upgrade -->
<Property Id="LAUNCH" Value="yes" />
<CustomAction Id="DoLaunch"
Directory="INSTALLDIR"
ExeCommand='"[INSTALLDIR]EDMarketConnector.exe"'
Return="asyncNoWait"
Execute="deferred"
Impersonate="yes"
/>
<InstallExecuteSequence>
<!-- http://alekdavis.blogspot.co.uk/2013/05/wix-woes-what-is-your-installer-doing.html -->
<Custom Action="DoLaunch" Before="InstallFinalize">
NOT Installed AND LAUNCH ~= "yes"
</Custom>
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<!-- http://wixtoolset.org/documentation/manual/v3/howtos/files_and_registry/write_a_registry_entry.html -->
<Component Id="RegistryEntries" Guid="*">
<RegistryKey Root="HKCR" Key="edmc">
<RegistryValue Type="string" Value="$(var.PRODUCTLONGNAME)"/>
<RegistryValue Type="string" Name="URL Protocol" Value=""/>
<RegistryKey Key="DefaultIcon">
<RegistryValue Type="string" Value="[INSTALLDIR]EDMarketConnector.exe,0"/>
</RegistryKey>
<RegistryKey Key="shell">
<RegistryKey Key="open">
<RegistryKey Key="command">
<RegistryValue Type="string" Value='"[INSTALLDIR]EDMarketConnector.exe" "%1"'/>
</RegistryKey>
<RegistryKey Key="ddeexec">
<RegistryValue Type="string" Value='Open("%1")'/>
</RegistryKey>
</RegistryKey>
</RegistryKey>
</RegistryKey>
</Component>
<!-- Contents auto-generated with heat.exe, see setup.py -->
<Directory Id="ProgramFilesFolder">
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
</Directory>
</Directory>
<!-- Contents auto-generated in setup.py -->
<Feature Id='Complete' Level='1'>
</Feature>
</Product>
</Wix>
<!-- Local Variables: -->
<!-- tab-width: 4 -->
<!-- End: -->