Skip to content

Commit aa89df7

Browse files
committed
Windows installer: fix shortcut folder removal issue, fix version upgrade issue
1 parent e28d60b commit aa89df7

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

wix/generic-DataLab.wxs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
<!-- Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. -->
22
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
33
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
4-
<Package Name="DataLab" ProductCode="b9f2e8d4-7c3a-4f1b-9e6d-5a8c2f1b4e9a" Language="1033" Version="{version}" Codepage="1252" Manufacturer="DataLab Platform Developers" UpgradeCode="e7a3f5c1-9d84-4b2a-a6f1-2c5d8e9b7a31" InstallerVersion="200" Scope="perUserOrMachine">
5-
<Upgrade Id="e7a3f5c1-9d84-4b2a-a6f1-2c5d8e9b7a31">
6-
<UpgradeVersion Minimum="1.0.0" Maximum="{version}" IncludeMinimum="yes" IncludeMaximum="no" OnlyDetect="no" Property="PREVIOUSVERSIONSINSTALLED" />
7-
<UpgradeVersion Minimum="{version}" OnlyDetect="yes" Property="NEWERVERSIONDETECTED" />
8-
</Upgrade>
9-
<CustomAction Id="PreventDowngrade" Error="A newer version of [ProductName] is already installed." />
10-
<InstallExecuteSequence>
11-
<Custom Action="PreventDowngrade" After="FindRelatedProducts" Condition="NEWERVERSIONDETECTED" />
12-
<RemoveExistingProducts After="InstallInitialize" />
13-
</InstallExecuteSequence>
14-
<Icon Id="DataLab.exe" SourceFile=".\resources\DataLab.ico" />
4+
<Package Name="DataLab" ProductCode="{product_code}" Language="1033" Version="{version}" Codepage="1252" Manufacturer="DataLab Platform Developers" UpgradeCode="e7a3f5c1-9d84-4b2a-a6f1-2c5d8e9b7a31" InstallerVersion="200" Scope="perUserOrMachine">
5+
<MajorUpgrade DowngradeErrorMessage="A newer or same version of [ProductName] is already installed. Please uninstall the existing version before installing this one." />
6+
<Icon Id="DataLabIcon" SourceFile=".\resources\DataLab.ico" />
157
<Icon Id="DataLabResetIcon" SourceFile=".\resources\DataLab-Reset.ico" />
168
<WixVariable Id="WixUILicenseRtf" Value=".\wix\license.rtf" />
179
<WixVariable Id="WixUIDialogBmp" Value=".\wix\dialog.bmp" />
@@ -51,12 +43,21 @@
5143
<File Source=".\dist\DataLab\manifest.json" />
5244
</Component>
5345
<!-- Automatically inserted components -->
54-
<Component Id="PC_Shortcuts" Directory="ApplicationProgramsFolder" Guid="858c3c36-978e-4edb-a2c3-cf5c91588bcf">
55-
<Shortcut Id="ApplicationStartMenuShortcut" Name="{display_folder_name}" Description="{display_folder_name}" Target="[INSTALLFOLDER]\DataLab.exe" WorkingDirectory="INSTALLFOLDER" />
46+
<!-- Shortcut components: one component per shortcut with registry KeyPath -->
47+
<Component Id="PC_Shortcut_Main" Directory="ApplicationProgramsFolder" Guid="*">
48+
<Shortcut Id="ApplicationStartMenuShortcut" Name="{display_folder_name}" Description="{display_folder_name}" Target="[INSTALLFOLDER]\DataLab.exe" WorkingDirectory="INSTALLFOLDER" Icon="DataLabIcon" />
49+
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\{install_folder_name}" Name="shortcut_main" Type="integer" Value="1" KeyPath="yes" />
50+
<RemoveFolder Id="RemoveApplicationProgramsFolder1" Directory="ApplicationProgramsFolder" On="uninstall" />
51+
</Component>
52+
<Component Id="PC_Shortcut_Reset" Directory="ApplicationProgramsFolder" Guid="*">
5653
<Shortcut Id="ResetApplicationStartMenuShortcut" Name="Reset {display_folder_name}" Description="Resets {display_folder_name} configuration" Target="[INSTALLFOLDER]\DataLab.exe" Arguments="--reset" WorkingDirectory="INSTALLFOLDER" Icon="DataLabResetIcon" />
57-
<Shortcut Id="UninstallProductShortcut" Name="Uninstall {display_folder_name}" Description="Uninstalls {display_folder_name}" Target="[System64Folder]msiexec.exe" Arguments="/x [ProductCode]" WorkingDirectory="INSTALLFOLDER" />
58-
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall" />
59-
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\{install_folder_name}" Name="installed" Type="integer" Value="1" KeyPath="yes" />
54+
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\{install_folder_name}" Name="shortcut_reset" Type="integer" Value="1" KeyPath="yes" />
55+
<RemoveFolder Id="RemoveApplicationProgramsFolder2" Directory="ApplicationProgramsFolder" On="uninstall" />
56+
</Component>
57+
<Component Id="PC_Shortcut_Uninstall" Directory="ApplicationProgramsFolder" Guid="*">
58+
<Shortcut Id="UninstallProductShortcut" Name="Uninstall {display_folder_name}" Description="Uninstalls {display_folder_name}" Target="[System64Folder]msiexec.exe" Arguments="/x [ProductCode]" WorkingDirectory="INSTALLFOLDER" Icon="DataLabIcon" />
59+
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\{install_folder_name}" Name="shortcut_uninstall" Type="integer" Value="1" KeyPath="yes" />
60+
<RemoveFolder Id="RemoveApplicationProgramsFolder3" Directory="ApplicationProgramsFolder" On="uninstall" />
6061
</Component>
6162
</ComponentGroup>
6263
</Fragment>

wix/makewxs.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ def make_wxs(product_name: str, version: str) -> None:
7474
# User-friendly folder name: "DataLab 1.0"
7575
display_folder_name = f"{product_name} {major_minor}"
7676

77+
# Generate a deterministic ProductCode based on MAJOR version only
78+
# All versions with the same major version (e.g., 1.0.0, 1.0.1, 1.1.0) will have
79+
# the same ProductCode, preventing installation of multiple v1.x versions.
80+
# Different major versions (v1.x vs v2.x) will have different ProductCodes,
81+
# allowing them to be installed side-by-side.
82+
upgrade_code = uuid.UUID("e7a3f5c1-9d84-4b2a-a6f1-2c5d8e9b7a31")
83+
product_code = str(uuid.uuid5(upgrade_code, f"v{major_version}"))
84+
7785
wix_dir = osp.abspath(osp.dirname(__file__))
7886
proj_dir = osp.join(wix_dir, os.pardir)
7987
dist_dir = osp.join(proj_dir, "dist", product_name)
@@ -162,6 +170,7 @@ def make_wxs(product_name: str, version: str) -> None:
162170
wxs = insert_text_after(dir_str, "<!-- Automatically inserted directories -->", wxs)
163171
wxs = insert_text_after(comp_str, "<!-- Automatically inserted components -->", wxs)
164172
wxs = wxs.replace("{version}", version_msi)
173+
wxs = wxs.replace("{product_code}", product_code)
165174
wxs = wxs.replace("{install_folder_name}", install_folder_name)
166175
wxs = wxs.replace("{display_folder_name}", display_folder_name)
167176
with open(output_path, "w", encoding="utf-8") as fd:

0 commit comments

Comments
 (0)