Skip to content

Commit

Permalink
(#3) Create new extension to provide compatibility
Browse files Browse the repository at this point in the history
This commit adds a new compatibility package to
prevent older packages to fail installation if this
package is installed on the user system.
  • Loading branch information
AdmiringWorm committed Mar 21, 2022
1 parent 0a47a15 commit 1ffba95
Show file tree
Hide file tree
Showing 10 changed files with 465 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/chocolatey-compatibility.extension/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# CHANGELOG

## 1.0.0

- Add compatibility layer for removed function `Install-ChocolateyDesktopLink`
- Add compatibility layer for removed function `Write-ChocolateyFailure`
- Add compatibility layer for removed function `Write-ChocolateySuccess`
- Add compatibility layer for removed function `Write-FileUpdateLog`
- Add support for `Get-PackageParameters`.
- Add support for `Get-UninstallRegistryKey`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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. -->
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>chocolatey-compatibility.extension</id>
<version>1.0.0</version>
<owners>chocolatey-community</owners>
<title>Chocolatey Compatibility Extension</title>
<authors>chocolatey-community</authors>
<projectUrl>https://github.com/chocolatey-community/chocolatey-extensions</projectUrl>
<!--<iconUrl>http://cdn.rawgit.com/chocolatey-coreteampackages/master/icons/chocolatey-common.extension.png</iconUrl>-->
<copyright>© 2022 Chocolatey Community Maintainers</copyright>
<licenseUrl>https://github.com/chocolatey-community/chocolatey-extensions/blob/master/LICENSE.md</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<projectSourceUrl>https://github.com/chocolatey-community/chocolatey-extensions/tree/master/src/chocolatey-compatibility.extension</projectSourceUrl>
<bugTrackerUrl>https://github.com/chocolatey-community/chocolatey-extensions/issues</bugTrackerUrl>
<tags>chocolatey-compatibility compatibility extension</tags>
<summary>Extension package to provide compatibility with older versions of Chocolatey</summary>
<description><![CDATA[
This package provides helper functions that re-introduces helpers that was removed or updated
in Chocolatey, as well as helpers that is not available in older version of Chocolatey CLI.
The purpose of the package is to allow older packages to keep functioning even on later versions
of Chocolatey CLI where certain helpers have been removed.
The helpers included in this package may not have any logic to handle the functionality to keep
existing, but rather to ensure that packages using the helpers do not stop working.
**WARNING: Do NOT use helper located in this package for removed functionality, unless absolutely necessary!**]]></description>
<releaseNotes>https://github.com/chocolatey-community/chocolatey-extensions/blob/master/src/chocolatey-compatibility.extension/CHANGELOG.md</releaseNotes>
</metadata>
<files>
<!-- this section controls what actually gets packaged into the Chocolatey package -->
<file src="extensions\**" target="extensions" />
</files>
</package>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Export functions that start with capital letter, and located in helpers directory.
# Other files are considered private, and should not be imported.
$ScriptRoot = Split-Path $MyInvocation.MyCommand.Definition

# The functions available in Chocolatey is not available in a variable
# we need to skip the import of a function if it already exist, as such
# we need to check the file system directly.
$ChocolateyScriptPath = Resolve-Path "$env:ChocolateyInstall\helpers\functions"

$existingMembers = Get-ChildItem $ChocolateyScriptPath | ForEach-Object BaseName

Get-ChildItem "$ScriptRoot\helpers\*.ps1" | `
Where-Object { $_.Name -cmatch "^[A-Z]+" } | `
ForEach-Object {
$name = $_.BaseName

if ($existingMembers -notcontains $name) {
Write-Debug "Exporting function '$name' for backwards compatibility"
. $_
Export-ModuleMember -Function $name
}
else {
Write-Debug "Function '$name' exists, ignoring export."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<#
.SYNOPSIS
Parses parameters of the package
.EXAMPLE
Get-PackageParameters "/Shortcut /InstallDir:'c:\program files\xyz' /NoStartup" | set r
if ($r.Shortcut) {... }
Write-Host $r.InstallDir
.OUTPUTS
[HashTable]
#>
function Get-PackageParameters {
[CmdletBinding()]
param(
[string] $Parameters = $Env:ChocolateyPackageParameters,
# Allows splatting with arguments that do not apply and future expansion. Do not use directly.
[parameter(ValueFromRemainingArguments = $true)]
[Object[]] $IgnoredArguments
)

$res = @{}

$re = "\/([a-zA-Z0-9]+)(:[`"'].+?[`"']|[^ ]+)?"
$results = $Parameters | Select-String $re -AllMatches | Select-Object -Expand Matches
foreach ($m in $results) {
if (!$m) { continue } # must because of posh 2.0 bug: https://github.com/chocolatey/chocolatey-coreteampackages/issues/465

$a = $m.Value -split ':'
$opt = $a[0].Substring(1); $val = $a[1..100] -join ':'
if ($val -match '^(".+")|(''.+'')$') {$val = $val -replace '^.|.$'}
$res[ $opt ] = if ($val) { $val } else { $true }
}
$res
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<#
.SYNOPSIS
Retrieve registry key(s) for system-installed applications from an exact or wildcard search.
.DESCRIPTION
This function will attempt to retrieve a matching registry key for an already installed application,
usually to be used with a chocolateyUninstall.ps1 automation script.
The function also prevents `Get-ItemProperty` from failing when handling wrongly encoded registry keys.
.PARAMETER SoftwareName
Part or all of the Display Name as you see it in Programs and Features.
It should be enough to be unique.
The syntax follows the rules of the PowerShell `-like` operator, so the `*` character is interpreted
as a wildcard, which matches any (zero or more) characters.
If the display name contains a version number, such as "Launchy (2.5)", it is recommended you use a
fuzzy search `"Launchy (*)"` (the wildcard `*`) so if Launchy auto-updates or is updated outside
of chocolatey, the uninstall script will not fail.
Take care not to abuse fuzzy/glob pattern searches. Be conscious of programs that may have shared
or common root words to prevent overmatching. For example, "SketchUp*" would match two keys with software
names "SketchUp 2016" and "SketchUp Viewer" that are different programs released by the same company.
.PARAMETER IgnoredArguments
Allows splatting with arguments that do not apply and future expansion. Do not use directly.
.INPUTS
System.String
.OUTPUTS
PSCustomObject
.EXAMPLE
[array]$key = Get-UninstallRegistryKey -SoftwareName "VLC media player"
$key.UninstallString
Exact match: software name in Programs and Features is "VLC media player"
.EXAMPLE
[array]$key = Get-UninstallRegistryKey -SoftwareName "Gpg4win (*)"
$key.UninstallString
Version match: software name is "Gpg4Win (2.3.0)"
.EXAMPLE
[array]$key = Get-UninstallRegistryKey -SoftwareName "SketchUp [0-9]*"
$key.UninstallString
Version match: software name is "SketchUp 2016"
Note that the similar software name "SketchUp Viewer" would not be matched.
.LINK
Uninstall-ChocolateyPackage
#>
function Get-UninstallRegistryKey {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[string] $SoftwareName,
[parameter(ValueFromRemainingArguments = $true)]
[Object[]] $IgnoredArguments
)
Write-Debug "Running 'Get-UninstallRegistryKey' for `'$env:ChocolateyPackageName`' with SoftwareName:`'$SoftwareName`'";

$ErrorActionPreference = 'Stop'
$local_key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
$machine_key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
$machine_key6432 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'

Write-Verbose "Retrieving all uninstall registry keys"
[array]$keys = Get-ChildItem -Path @($machine_key6432, $machine_key, $local_key) -ea 0
Write-Debug "Registry uninstall keys on system: $($keys.Count)"

Write-Debug "Error handling check: `'Get-ItemProperty`' fails if a registry key is encoded incorrectly."
[int]$maxAttempts = $keys.Count
for ([int]$attempt = 1; $attempt -le $maxAttempts; $attempt++) {
$success = $false

$keyPaths = $keys | Select-Object -ExpandProperty PSPath
try {
[array]$foundKey = Get-ItemProperty -Path $keyPaths -ea 0 | Where-Object { $_.DisplayName -like $SoftwareName }
$success = $true
}
catch {
Write-Debug "Found bad key."
foreach ($key in $keys) { try { Get-ItemProperty $key.PsPath > $null } catch { $badKey = $key.PsPath } }
Write-Verbose "Skipping bad key: $badKey"
[array]$keys = $keys | Where-Object { $badKey -NotContains $_.PsPath }
}

if ($success) { break; }
if ($attempt -eq 10) {
Write-Warning "Found more than 10 bad registry keys. Run command again with `'--verbose --debug`' for more info."
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."
}
}

Write-Debug "Found $($foundKey.Count) uninstall registry key(s) with SoftwareName:`'$SoftwareName`'";
return $foundKey
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright © 2017 - 2021 Chocolatey Software, Inc.
# Copyright © 2015 - 2017 RealDimensions Software, LLC
# Copyright © 2011 - 2015 RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Install-ChocolateyDesktopLink {
<#
.SYNOPSIS
DEPRECATED - This adds a shortcut on the desktop to the specified file path.
.DESCRIPTION
Determines the desktop folder and creates a shortcut to the specified
file path. Will not throw errors if it fails.
It is recommended you use `Install-ChocolateyShortcut` instead of this
method as this has been removed upstream.
.NOTES
This function was removed and deprecated in Chocolatey CLI in favor of using
https://docs.chocolatey.org/en-us/create/functions/install-chocolateyshortcut.
As the recommendation is to no longer use this function, no updates
will be accepted to fix any problems.
Compared to original function that was available in Chocolatey CLI, this
implementation do not include any error handling, nor any promise that shortcuts
will be created in the same way as Chocolatey CLI did it.
.INPUTS
None
.OUTPUTS
None
.PARAMETER TargetFilePath
This is the location to the application/executable file that you want to
add a shortcut to on the desktop. This is mandatory.
.PARAMETER IgnoredArguments
Allows splatting with arguments that do not apply. Do not use directly.
.LINK
Install-ChocolateyShortcut
#>
param(
[parameter(Mandatory = $true, Position = 0)][string] $targetFilePath,
[parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments
)
Write-Warning "Install-ChocolateyDesktopLink was removed in Chocolatey CLI v1. If you are the package maintainer, please use Install-ChocolateyShortcut instead."
Write-Warning "If you are not the maintainer, please contact the maintainer to update the $env:ChocolateyPackageName package."
Write-Warning "There is no guarantee that this function works as expected compared to original function in Chocolatey CLI pre 1.0.0"

if (!$targetFilePath) {
throw "Install-ChocolateyDesktopLink - `$targetFilePath can not be null."
}

if (!(Test-Path($targetFilePath))) {
Write-Warning "'$targetFilePath' does not exist. If it is not created the shortcut will not be valid."
}

Write-Debug "Creating Shortcut..."

try {
$desktop = $([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::DesktopDirectory))
if (!(Test-Path($desktop))) {
[System.IO.Directory]::CreateDirectory($desktop) | Out-Null
}
$link = Join-Path $desktop "$([System.IO.Path]::GetFileName($targetFilePath)).lnk"
$workingDirectory = $([System.IO.Path]::GetDirectoryName($targetFilePath))

$wshshell = New-Object -ComObject WScript.Shell
$lnk = $wshshell.CreateShortcut($link)
$lnk.TargetPath = $targetFilePath
$lnk.WorkingDirectory = $workingDirectory
$lnk.Save()

Write-Host "Desktop Shortcut created pointing at `'$targetFilePath`'."
}
catch {
Write-Warning "Unable to create desktop link. Error captured was $($_.Exception.Message)."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright © 2017 - 2021 Chocolatey Software, Inc.
# Copyright © 2015 - 2017 RealDimensions Software, LLC
# Copyright © 2011 - 2015 RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Write-ChocolateyFailure {
<#
.SYNOPSIS
DEPRECATED - DO NOT USE. This function was removed in Chocolatey v1.
.DESCRIPTION
Throws the error message as an error.
.NOTES
This has been deprecated and was no longer useful as of 0.9.9,
in 1.0.0 this function was removed entirely from Chocolatey CLI. Instead
please just use `throw $_.Exception` when catching errors. Although
try/catch is no longer necessary unless you want to do some error
handling.
As the recommendation is to no longer use this function, no updates
will be accepted to fix any problems.
.INPUTS
None
.OUTPUTS
None
.PARAMETER PackageName
The name of the package - while this is an arbitrary value, it's
recommended that it matches the package id.
.PARAMETER FailureMessage
The message to throw an error with.
.PARAMETER IgnoredArguments
Allows splatting with arguments that do not apply. Do not use directly.
.LINK
Write-ChocolateySuccess
#>
param(
[string] $packageName,
[string] $failureMessage,
[parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments
)

Write-FunctionCallLogMessage -Invocation $MyInvocation -Parameters $PSBoundParameters
Write-Warning "Write-ChocolateyFailure was removed in Chocolatey CLI v1. If you are the package maintainer, please use 'throw `$_.Exception' instead."
Write-Warning "If you are not the maintainer, please contact the maintainer to update the $packageName package."

$error | ForEach-Object { $_.Exception | Format-List * | Out-String }

throw "$failureMessage"
}
Loading

0 comments on commit 1ffba95

Please sign in to comment.