Skip to content

Commit 57bade6

Browse files
committed
(#3) Create new extension to provide compatibility
This commit adds a new compatibility package to prevent older packages to fail installation if this package is installed on the user system.
1 parent 0a47a15 commit 57bade6

10 files changed

+472
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# CHANGELOG
2+
3+
## 1.0.0
4+
5+
- Add compatibility layer for removed function `Install-ChocolateyDesktopLink`
6+
- Add compatibility layer for removed function `Write-ChocolateyFailure`
7+
- Add compatibility layer for removed function `Write-ChocolateySuccess`
8+
- Add compatibility layer for removed function `Write-FileUpdateLog`
9+
- Add support for `Get-PackageParameters`.
10+
- Add support for `Get-UninstallRegistryKey`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
3+
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
4+
<metadata>
5+
<id>chocolatey-compatibility.extension</id>
6+
<version>1.0.0</version>
7+
<owners>chocolatey-community</owners>
8+
<title>Chocolatey Compatibility Extension</title>
9+
<authors>chocolatey-community</authors>
10+
<projectUrl>https://github.com/chocolatey-community/chocolatey-extensions</projectUrl>
11+
<!--<iconUrl>http://cdn.rawgit.com/chocolatey-coreteampackages/master/icons/chocolatey-common.extension.png</iconUrl>-->
12+
<copyright>© 2022 Chocolatey Community Maintainers</copyright>
13+
<licenseUrl>https://github.com/chocolatey-community/chocolatey-extensions/blob/master/LICENSE.md</licenseUrl>
14+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
15+
<projectSourceUrl>https://github.com/chocolatey-community/chocolatey-packages/tree/master/src/chocolatey-compatibility.extension</projectSourceUrl>
16+
<bugTrackerUrl>https://github.com/chocolatey-community/chocolatey-extensions/issues</bugTrackerUrl>
17+
<tags>chocolatey-compatibility compatibility extension</tags>
18+
<summary>Extension package to provide compatibility with older versions of Chocolatey</summary>
19+
<description><![CDATA[
20+
This package provides helper functions that re-introduces helpers that was removed or updated
21+
in Chocolatey, as well as helpers that is not available in older version of Chocolatey CLI.
22+
The purpose of the package is to allow older packages to keep functioning even on later versions
23+
of Chocolatey CLI where certain helpers have been removed.
24+
25+
The helpers included in this package may not have any logic to handle the functionality to keep
26+
existing, but rather to ensure that packages using the helpers do not stop working.
27+
28+
**WARNING: Do NOT use helper located in this package for removed functionality, unless absolutely necessary!**]]></description>
29+
<releaseNotes>## 1.0.0
30+
31+
- Add compatibility layer for removed function `Install-ChocolateyDesktopLink`
32+
- Add compatibility layer for removed function `Write-ChocolateyFailure`
33+
- Add compatibility layer for removed function `Write-ChocolateySuccess`
34+
- Add compatibility layer for removed function `Write-FileUpdateLog`
35+
- Add support for `Get-PackageParameters`.
36+
- Add support for `Get-UninstallRegistryKey`.</releaseNotes>
37+
</metadata>
38+
<files>
39+
<!-- this section controls what actually gets packaged into the Chocolatey package -->
40+
<file src="extensions\**" target="extensions" />
41+
</files>
42+
</package>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Export functions that start with capital letter, and located in helpers directory.
2+
# Other files are considered private, and should not be imported.
3+
$ScriptRoot = Split-Path $MyInvocation.MyCommand.Definition
4+
5+
# The functions available in Chocolatey is not available in a variable
6+
# we need to skip the import of a function if it already exist, as such
7+
# we need to check the file system directly.
8+
$ChocolateyScriptPath = Resolve-Path "$env:ChocolateyInstall\helpers\functions"
9+
10+
$existingMembers = Get-ChildItem $ChocolateyScriptPath | ForEach-Object BaseName
11+
12+
Get-ChildItem "$ScriptRoot\helpers\*.ps1" | `
13+
Where-Object { $_.Name -cmatch "^[A-Z]+" } | `
14+
ForEach-Object {
15+
$name = $_.BaseName
16+
17+
if ($existingMembers -notcontains $name) {
18+
Write-Debug "Exporting function '$name' for backwards compatibility"
19+
. $_
20+
Export-ModuleMember -Function $name
21+
}
22+
else {
23+
Write-Debug "Function '$name' exists, ignoring export."
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<#
2+
.SYNOPSIS
3+
Parses parameters of the package
4+
5+
.EXAMPLE
6+
Get-PackageParameters "/Shortcut /InstallDir:'c:\program files\xyz' /NoStartup" | set r
7+
if ($r.Shortcut) {... }
8+
Write-Host $r.InstallDir
9+
10+
.OUTPUTS
11+
[HashTable]
12+
#>
13+
function Get-PackageParameters {
14+
[CmdletBinding()]
15+
param(
16+
[string] $Parameters = $Env:ChocolateyPackageParameters,
17+
# Allows splatting with arguments that do not apply and future expansion. Do not use directly.
18+
[parameter(ValueFromRemainingArguments = $true)]
19+
[Object[]] $IgnoredArguments
20+
)
21+
22+
$res = @{}
23+
24+
$re = "\/([a-zA-Z0-9]+)(:[`"'].+?[`"']|[^ ]+)?"
25+
$results = $Parameters | Select-String $re -AllMatches | Select-Object -Expand Matches
26+
foreach ($m in $results) {
27+
if (!$m) { continue } # must because of posh 2.0 bug: https://github.com/chocolatey/chocolatey-coreteampackages/issues/465
28+
29+
$a = $m.Value -split ':'
30+
$opt = $a[0].Substring(1); $val = $a[1..100] -join ':'
31+
if ($val -match '^(".+")|(''.+'')$') {$val = $val -replace '^.|.$'}
32+
$res[ $opt ] = if ($val) { $val } else { $true }
33+
}
34+
$res
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<#
2+
.SYNOPSIS
3+
Retrieve registry key(s) for system-installed applications from an exact or wildcard search.
4+
5+
.DESCRIPTION
6+
This function will attempt to retrieve a matching registry key for an already installed application,
7+
usually to be used with a chocolateyUninstall.ps1 automation script.
8+
9+
The function also prevents `Get-ItemProperty` from failing when handling wrongly encoded registry keys.
10+
11+
.PARAMETER SoftwareName
12+
Part or all of the Display Name as you see it in Programs and Features.
13+
It should be enough to be unique.
14+
The syntax follows the rules of the PowerShell `-like` operator, so the `*` character is interpreted
15+
as a wildcard, which matches any (zero or more) characters.
16+
17+
If the display name contains a version number, such as "Launchy (2.5)", it is recommended you use a
18+
fuzzy search `"Launchy (*)"` (the wildcard `*`) so if Launchy auto-updates or is updated outside
19+
of chocolatey, the uninstall script will not fail.
20+
21+
Take care not to abuse fuzzy/glob pattern searches. Be conscious of programs that may have shared
22+
or common root words to prevent overmatching. For example, "SketchUp*" would match two keys with software
23+
names "SketchUp 2016" and "SketchUp Viewer" that are different programs released by the same company.
24+
25+
.PARAMETER IgnoredArguments
26+
Allows splatting with arguments that do not apply and future expansion. Do not use directly.
27+
28+
.INPUTS
29+
System.String
30+
31+
.OUTPUTS
32+
PSCustomObject
33+
34+
.EXAMPLE
35+
[array]$key = Get-UninstallRegistryKey -SoftwareName "VLC media player"
36+
$key.UninstallString
37+
38+
Exact match: software name in Programs and Features is "VLC media player"
39+
40+
.EXAMPLE
41+
[array]$key = Get-UninstallRegistryKey -SoftwareName "Gpg4win (*)"
42+
$key.UninstallString
43+
44+
Version match: software name is "Gpg4Win (2.3.0)"
45+
46+
.EXAMPLE
47+
[array]$key = Get-UninstallRegistryKey -SoftwareName "SketchUp [0-9]*"
48+
$key.UninstallString
49+
50+
Version match: software name is "SketchUp 2016"
51+
Note that the similar software name "SketchUp Viewer" would not be matched.
52+
53+
.LINK
54+
Uninstall-ChocolateyPackage
55+
#>
56+
function Get-UninstallRegistryKey {
57+
[CmdletBinding()]
58+
param(
59+
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
60+
[ValidateNotNullOrEmpty()]
61+
[string] $SoftwareName,
62+
[parameter(ValueFromRemainingArguments = $true)]
63+
[Object[]] $IgnoredArguments
64+
)
65+
Write-Debug "Running 'Get-UninstallRegistryKey' for `'$env:ChocolateyPackageName`' with SoftwareName:`'$SoftwareName`'";
66+
67+
$ErrorActionPreference = 'Stop'
68+
$local_key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
69+
$machine_key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
70+
$machine_key6432 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
71+
72+
Write-Verbose "Retrieving all uninstall registry keys"
73+
[array]$keys = Get-ChildItem -Path @($machine_key6432, $machine_key, $local_key) -ea 0
74+
Write-Debug "Registry uninstall keys on system: $($keys.Count)"
75+
76+
Write-Debug "Error handling check: `'Get-ItemProperty`' fails if a registry key is encoded incorrectly."
77+
[int]$maxAttempts = $keys.Count
78+
for ([int]$attempt = 1; $attempt -le $maxAttempts; $attempt++) {
79+
$success = $false
80+
81+
$keyPaths = $keys | Select-Object -ExpandProperty PSPath
82+
try {
83+
[array]$foundKey = Get-ItemProperty -Path $keyPaths -ea 0 | Where-Object { $_.DisplayName -like $SoftwareName }
84+
$success = $true
85+
}
86+
catch {
87+
Write-Debug "Found bad key."
88+
foreach ($key in $keys) { try { Get-ItemProperty $key.PsPath > $null } catch { $badKey = $key.PsPath } }
89+
Write-Verbose "Skipping bad key: $badKey"
90+
[array]$keys = $keys | Where-Object { $badKey -NotContains $_.PsPath }
91+
}
92+
93+
if ($success) { break; }
94+
if ($attempt -eq 10) {
95+
Write-Warning "Found more than 10 bad registry keys. Run command again with `'--verbose --debug`' for more info."
96+
Write-Debug "Each key searched should correspond to an installed program. It is very unlikely to have more than a few programs with incorrectly encoded keys, if any at all. This may be indicative of one or more corrupted registry branches."
97+
}
98+
}
99+
100+
Write-Debug "Found $($foundKey.Count) uninstall registry key(s) with SoftwareName:`'$SoftwareName`'";
101+
return $foundKey
102+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copyright © 2017 - 2021 Chocolatey Software, Inc.
2+
# Copyright © 2015 - 2017 RealDimensions Software, LLC
3+
# Copyright © 2011 - 2015 RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
function Install-ChocolateyDesktopLink {
18+
<#
19+
.SYNOPSIS
20+
DEPRECATED - This adds a shortcut on the desktop to the specified file path.
21+
22+
.DESCRIPTION
23+
Determines the desktop folder and creates a shortcut to the specified
24+
file path. Will not throw errors if it fails.
25+
It is recommended you use `Install-ChocolateyShortcut` instead of this
26+
method as this has been removed upstream.
27+
28+
.NOTES
29+
This function was removed and deprecated in Chocolatey CLI in favor of using
30+
https://docs.chocolatey.org/en-us/create/functions/install-chocolateyshortcut.
31+
As the recommendation is to no longer use this function, no updates
32+
will be accepted to fix any problems.
33+
Compared to original function that was available in Chocolatey CLI, this
34+
implementation do not include any error handling, nor any promise that shortcuts
35+
will be created in the same way as Chocolatey CLI did it.
36+
37+
.INPUTS
38+
None
39+
40+
.OUTPUTS
41+
None
42+
43+
.PARAMETER TargetFilePath
44+
This is the location to the application/executable file that you want to
45+
add a shortcut to on the desktop. This is mandatory.
46+
47+
.PARAMETER IgnoredArguments
48+
Allows splatting with arguments that do not apply. Do not use directly.
49+
50+
.LINK
51+
Install-ChocolateyShortcut
52+
#>
53+
param(
54+
[parameter(Mandatory = $true, Position = 0)][string] $targetFilePath,
55+
[parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments
56+
)
57+
Write-Warning "Install-ChocolateyDesktopLink was removed in Chocolatey CLI v1. If you are the package maintainer, please use Install-ChocolateyShortcut instead."
58+
Write-Warning "If you are not the maintainer, please contact the maintainer to update the $env:ChocolateyPackageName package."
59+
Write-Warning "There is no guarantee that this function works as expected compared to original function in Chocolatey CLI pre 1.0.0"
60+
61+
if (!$targetFilePath) {
62+
throw "Install-ChocolateyDesktopLink - `$targetFilePath can not be null."
63+
}
64+
65+
if (!(Test-Path($targetFilePath))) {
66+
Write-Warning "'$targetFilePath' does not exist. If it is not created the shortcut will not be valid."
67+
}
68+
69+
Write-Debug "Creating Shortcut..."
70+
71+
try {
72+
$desktop = $([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::DesktopDirectory))
73+
if (!(Test-Path($desktop))) {
74+
[System.IO.Directory]::CreateDirectory($desktop) | Out-Null
75+
}
76+
$link = Join-Path $desktop "$([System.IO.Path]::GetFileName($targetFilePath)).lnk"
77+
$workingDirectory = $([System.IO.Path]::GetDirectoryName($targetFilePath))
78+
79+
$wshshell = New-Object -ComObject WScript.Shell
80+
$lnk = $wshshell.CreateShortcut($link)
81+
$lnk.TargetPath = $targetFilePath
82+
$lnk.WorkingDirectory = $workingDirectory
83+
$lnk.Save()
84+
85+
Write-Host "Desktop Shortcut created pointing at `'$targetFilePath`'."
86+
}
87+
catch {
88+
Write-Warning "Unable to create desktop link. Error captured was $($_.Exception.Message)."
89+
}
90+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright © 2017 - 2021 Chocolatey Software, Inc.
2+
# Copyright © 2015 - 2017 RealDimensions Software, LLC
3+
# Copyright © 2011 - 2015 RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
function Write-ChocolateyFailure {
18+
<#
19+
.SYNOPSIS
20+
DEPRECATED - DO NOT USE. This function was removed in Chocolatey v1.
21+
22+
.DESCRIPTION
23+
Throws the error message as an error.
24+
25+
.NOTES
26+
This has been deprecated and was no longer useful as of 0.9.9,
27+
in 1.0.0 this function was removed entirely from Chocolatey CLI. Instead
28+
please just use `throw $_.Exception` when catching errors. Although
29+
try/catch is no longer necessary unless you want to do some error
30+
handling.
31+
As the recommendation is to no longer use this function, no updates
32+
will be accepted to fix any problems.
33+
34+
.INPUTS
35+
None
36+
37+
.OUTPUTS
38+
None
39+
40+
.PARAMETER PackageName
41+
The name of the package - while this is an arbitrary value, it's
42+
recommended that it matches the package id.
43+
44+
.PARAMETER FailureMessage
45+
The message to throw an error with.
46+
47+
.PARAMETER IgnoredArguments
48+
Allows splatting with arguments that do not apply. Do not use directly.
49+
50+
.LINK
51+
Write-ChocolateySuccess
52+
#>
53+
param(
54+
[string] $packageName,
55+
[string] $failureMessage,
56+
[parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments
57+
)
58+
59+
Write-FunctionCallLogMessage -Invocation $MyInvocation -Parameters $PSBoundParameters
60+
Write-Warning "Write-ChocolateyFailure was removed in Chocolatey CLI v1. If you are the package maintainer, please use 'throw `$_.Exception' instead."
61+
Write-Warning "If you are not the maintainer, please contact the maintainer to update the $packageName package."
62+
63+
$error | ForEach-Object { $_.Exception | Format-List * | Out-String }
64+
65+
throw "$failureMessage"
66+
}

0 commit comments

Comments
 (0)