mirror of
https://github.com/MAKS-IT-COM/maksit-cluster-console.git
synced 2026-09-30 00:38:10 +02:00
(bugfix): keep one desktop shortcut across windows setup upgrades
This commit is contained in:
parent
f74e01700f
commit
7e8a4032e2
@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.8.1] - 2026-09-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Windows setup keeps a single desktop shortcut across upgrades. An icon that is already there stays when the checkbox is off, and a checked box no longer leaves a second `.lnk` or a `(2)` copy.
|
||||
|
||||
## [0.8.0] - 2026-09-26
|
||||
|
||||
### Added
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>0.8.0</Version>
|
||||
<Version>0.8.1</Version>
|
||||
<Product>MaksIT.ClusterConsole</Product>
|
||||
<AssemblyTitle>MaksIT.ClusterConsole</AssemblyTitle>
|
||||
</PropertyGroup>
|
||||
|
||||
@ -323,8 +323,33 @@ function New-WixPackageXml {
|
||||
$desktopProp = $xml.CreateElement('Property', $ns)
|
||||
$null = $desktopProp.SetAttribute('Id', 'INSTALLDESKTOPSHORTCUT')
|
||||
$null = $desktopProp.SetAttribute('Value', '0')
|
||||
$null = $desktopProp.SetAttribute('Secure', 'yes')
|
||||
$null = $package.AppendChild($desktopProp)
|
||||
|
||||
# Present when a previous install wrote the desktop shortcut marker.
|
||||
# Burn also searches HKCU as the user and passes DESKTOPSHORTCUTFOUND,
|
||||
# because a per-machine execute sequence runs as SYSTEM.
|
||||
$foundProp = $xml.CreateElement('Property', $ns)
|
||||
$null = $foundProp.SetAttribute('Id', 'DESKTOPSHORTCUTFOUND')
|
||||
$null = $foundProp.SetAttribute('Secure', 'yes')
|
||||
$foundSearch = $xml.CreateElement('RegistrySearch', $ns)
|
||||
$null = $foundSearch.SetAttribute('Id', 'DesktopShortcutFoundSearch')
|
||||
$null = $foundSearch.SetAttribute('Root', 'HKCU')
|
||||
$null = $foundSearch.SetAttribute('Key', "Software\$Manufacturer\$AppName")
|
||||
$null = $foundSearch.SetAttribute('Name', 'desktop')
|
||||
$null = $foundSearch.SetAttribute('Type', 'raw')
|
||||
$null = $foundProp.AppendChild($foundSearch)
|
||||
$null = $package.AppendChild($foundProp)
|
||||
|
||||
# Checkbox off on reinstall must not drop an icon that is already there.
|
||||
# Major upgrade removes the previous shortcut; this installs that one again.
|
||||
$keepShortcut = $xml.CreateElement('SetProperty', $ns)
|
||||
$null = $keepShortcut.SetAttribute('Id', 'INSTALLDESKTOPSHORTCUT')
|
||||
$null = $keepShortcut.SetAttribute('Value', '1')
|
||||
$null = $keepShortcut.SetAttribute('Before', 'CostFinalize')
|
||||
$null = $keepShortcut.SetAttribute('Condition', 'DESKTOPSHORTCUTFOUND = "1"')
|
||||
$null = $package.AppendChild($keepShortcut)
|
||||
|
||||
$productFolder = Get-DesktopInstallFolderName `
|
||||
-AppName $AppName `
|
||||
-Manufacturer $Manufacturer `
|
||||
@ -449,7 +474,8 @@ function New-WixPackageXml {
|
||||
$desktop = $xml.CreateElement('Component', $ns)
|
||||
$null = $desktop.SetAttribute('Id', 'DesktopShortcut')
|
||||
$null = $desktop.SetAttribute('Directory', 'DesktopFolder')
|
||||
$null = $desktop.SetAttribute('Guid', '*')
|
||||
$shortcutGuid = Get-DesktopShortcutComponentGuid -Manufacturer $Manufacturer -AppName $AppName
|
||||
$null = $desktop.SetAttribute('Guid', $shortcutGuid.ToString('D'))
|
||||
$null = $desktop.SetAttribute('Condition', 'INSTALLDESKTOPSHORTCUT = 1')
|
||||
$desktopShortcut = $xml.CreateElement('Shortcut', $ns)
|
||||
$null = $desktopShortcut.SetAttribute('Id', 'AppDesktopShortcut')
|
||||
@ -461,6 +487,26 @@ function New-WixPackageXml {
|
||||
}
|
||||
|
||||
$null = $desktop.AppendChild($desktopShortcut)
|
||||
# Same file name is replaced. A second ".lnk" (and the "(2)" copy) is removed
|
||||
# before CreateShortcuts so a checked box does not leave two desktop icons.
|
||||
$cleanupNames = [System.Collections.Generic.List[string]]::new()
|
||||
$cleanupNames.Add($productFolder)
|
||||
if (-not $cleanupNames.Contains($AppName)) {
|
||||
$cleanupNames.Add($AppName)
|
||||
}
|
||||
|
||||
$cleanupIndex = 0
|
||||
foreach ($shortcutName in $cleanupNames) {
|
||||
foreach ($suffix in @('', ' (2)')) {
|
||||
$cleanupIndex++
|
||||
$removeLnk = $xml.CreateElement('RemoveFile', $ns)
|
||||
$null = $removeLnk.SetAttribute('Id', "DesktopShortcutCleanup$cleanupIndex")
|
||||
$null = $removeLnk.SetAttribute('Name', "$shortcutName$suffix.lnk")
|
||||
$null = $removeLnk.SetAttribute('On', 'install')
|
||||
$null = $desktop.AppendChild($removeLnk)
|
||||
}
|
||||
}
|
||||
|
||||
$desktopReg = $xml.CreateElement('RegistryValue', $ns)
|
||||
$null = $desktopReg.SetAttribute('Root', 'HKCU')
|
||||
$null = $desktopReg.SetAttribute('Key', "Software\$Manufacturer\$AppName")
|
||||
@ -874,6 +920,27 @@ function Assert-FlatpakAppId {
|
||||
}
|
||||
}
|
||||
|
||||
function Get-DesktopShortcutComponentGuid {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Manufacturer,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$AppName
|
||||
)
|
||||
|
||||
$identity = "maksit-desktop-shortcut|$Manufacturer|$AppName"
|
||||
$md5 = [System.Security.Cryptography.MD5]::Create()
|
||||
try {
|
||||
$hash = $md5.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($identity))
|
||||
}
|
||||
finally {
|
||||
$md5.Dispose()
|
||||
}
|
||||
|
||||
return [guid]::new($hash)
|
||||
}
|
||||
|
||||
function Get-DerivedBundleUpgradeCode {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
@ -1196,15 +1263,18 @@ function New-WixBundleXml {
|
||||
$folderRoot + $Manufacturer + '\' + $productFolder
|
||||
}
|
||||
$escapedFolder = [System.Security.SecurityElement]::Escape($folderPath)
|
||||
$escapedShortcutKey = [System.Security.SecurityElement]::Escape("Software\$Manufacturer\$AppName")
|
||||
|
||||
# WiX v7 Bundle has no Scope attribute (WIX0004). MSI Package/@Scope plus
|
||||
# InstallFolder tokens decide per-machine vs per-user; Burn infers bundle scope.
|
||||
return @"
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||
<Bundle Name="$escapedName" Manufacturer="$escapedMfr" Version="$ProductVersion" UpgradeCode="$($bundleUpgrade.ToString('D'))"$iconAttr>
|
||||
<Variable Name="InstallFolder" Type="formatted" Value="$escapedFolder" bal:Overridable="yes" />
|
||||
<Variable Name="InstallDesktopShortcut" Type="numeric" Value="0" bal:Overridable="yes" />
|
||||
<Variable Name="DesktopShortcutFound" Type="string" Value="" bal:Overridable="yes" />
|
||||
<util:RegistrySearch Id="DesktopShortcutFoundSearch" Variable="DesktopShortcutFound" Root="HKCU" Key="$escapedShortcutKey" Value="desktop" Result="exists" />
|
||||
<BootstrapperApplication>
|
||||
<bal:WixStandardBootstrapperApplication Theme="$theme" LicenseUrl=""$logoAttrs />
|
||||
</BootstrapperApplication>
|
||||
@ -1212,6 +1282,7 @@ function New-WixBundleXml {
|
||||
<MsiPackage SourceFile="$escapedMsi" Compressed="yes" Vital="yes">
|
||||
<MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
|
||||
<MsiProperty Name="INSTALLDESKTOPSHORTCUT" Value="[InstallDesktopShortcut]" />
|
||||
<MsiProperty Name="DESKTOPSHORTCUTFOUND" Value="[DesktopShortcutFound]" />
|
||||
</MsiPackage>
|
||||
</Chain>
|
||||
</Bundle>
|
||||
|
||||
@ -13,7 +13,8 @@
|
||||
per-machine installs go to `C:\Program Files`, not Program Files (x86).
|
||||
Requires the WiX CLI (`dotnet tool install -g wix`). WiX v7: accept the
|
||||
OSMF EULA (`wix eula accept wix7` or `-acceptEula wix7`) and
|
||||
`wix extension add -g WixToolset.BootstrapperApplications.wixext`.
|
||||
`wix extension add -g WixToolset.BootstrapperApplications.wixext` and
|
||||
`wix extension add -g WixToolset.Util.wixext`.
|
||||
Reopen the shell so `%USERPROFILE%\.dotnet\tools` is on PATH.
|
||||
#>
|
||||
|
||||
@ -40,7 +41,7 @@ function Test-WixMissingException {
|
||||
}
|
||||
|
||||
function Get-WixMissingInstallMessage {
|
||||
return "WiX CLI ('wix') is not on PATH. Install with: dotnet tool install -g wix. For WiX v7 also run: wix eula accept wix7; wix extension add -g WixToolset.BootstrapperApplications.wixext. Reopen the terminal so %USERPROFILE%\.dotnet\tools is on PATH."
|
||||
return "WiX CLI ('wix') is not on PATH. Install with: dotnet tool install -g wix. For WiX v7 also run: wix eula accept wix7; wix extension add -g WixToolset.BootstrapperApplications.wixext; wix extension add -g WixToolset.Util.wixext. Reopen the terminal so %USERPROFILE%\.dotnet\tools is on PATH."
|
||||
}
|
||||
|
||||
function Get-WixCliVersionText {
|
||||
@ -280,7 +281,7 @@ function Invoke-Plugin {
|
||||
|
||||
Write-Log -Level "STEP" -Message "Building Windows installer exe ($wixArch)..."
|
||||
try {
|
||||
Invoke-ExternalCommand -Name wix -ArgumentList (@('build') + $eulaArgs + $archArgs + @($bundleWxsPath, '-ext', $bundleExt, '-o', $exePath)) | Out-Null
|
||||
Invoke-ExternalCommand -Name wix -ArgumentList (@('build') + $eulaArgs + $archArgs + @($bundleWxsPath, '-ext', $bundleExt, '-ext', 'WixToolset.Util.wixext', '-o', $exePath)) | Out-Null
|
||||
}
|
||||
catch {
|
||||
if (Test-WixMissingException -ErrorRecord $_) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user