Chocolatey-coreteampackages: (chocolatey-core.extension) Get-AppInstallLocation returns wrong results for paint.net

Created on 9 Oct 2017  路  5Comments  路  Source: chocolatey-community/chocolatey-coreteampackages

Expected Behavior

Given the following UninstallString value in the registry:

MsiExec.exe /X{guid}

Get-AppInstallLocation should not return "MsiExec.exe ", but ignore this value (as it does not contain path information) and proceed to check subsequent locations (Program Files, App Paths etc.).

Current Behavior

Get-AppInstallLocation returns "MsiExec.exe ", which is wrong on many levels:

  • has no path information
  • points to an executable, not to a directory
  • contains a trailing space

Possible Solution

Enhance registry value parsing code so that it

  • handles values containing command line arguments (Windows Installer packages use it, "X:\Path\y.exe /Uninstall" is also common) trims the extracted path,
  • tests the extracted path to verify it really exists, is absolute and is a directory.

Steps to Reproduce (for bugs)

cinst -y paint.net

Context

The paint.net package passes the bogus value obtained from Get-AppInstallLocation to Register-Application, which throws an error and the entire package installation fails.

Also reported on Disqus: https://chocolatey.org/packages/paint.net#comment-3558201902

Your Environment

3 - Done Bug Wontfix

All 5 comments

Hm.... works on my machine, and the value IS tested:

https://github.com/chocolatey/chocolatey-coreteampackages/blob/3e6890d01c90eb2e7bbdbd7c5c5fd3f14e187d32/extensions/chocolatey-core.extension/extensions/Get-AppInstallLocation.ps1#L45

> import-module C:\ProgramData\chocolatey\helpers\chocolateyInstaller.psm1

> Get-AppInstallLocation 'Paint.NET*' -Verbose
VERBOSE: Trying local and machine (x32 & x64) Uninstall keys
VERBOSE: Retrieving all uninstall registry keys
VERBOSE: Trying Uninstall key property 'InstallLocation'
VERBOSE: Trying Uninstall key property 'UninstallString'
VERBOSE: Trying Uninstall key property 'DisplayIcon'
VERBOSE: Trying Program Files with 2 levels depth: C:\Program Files C:\Program Files\*\* C:\Program Files (x86) C:\Program Files (x86)\*\*
C:\Program Files\paint.net

Try cd'ing to $Env:SystemRoot\System32:

PS C:\> Import-Module C:\ProgramData\chocolatey\helpers\chocolateyInstaller.psm1 PS C:\> Get-AppInstallLocation 'Paint.NET*' -Verbose -OutVariable x | % { "[$_]" } VERBOSE: Trying local and machine (x32 & x64) Uninstall keys VERBOSE: Retrieving all uninstall registry keys VERBOSE: Trying Uninstall key property 'InstallLocation' VERBOSE: Trying Uninstall key property 'UninstallString' VERBOSE: Trying Uninstall key property 'DisplayIcon' VERBOSE: Trying Program Files with 2 levels depth: C:\Program Files C:\Program Files\*\* C:\Program Files (x86) C:\Program Files (x86)\*\* [C:\Program Files\paint.net] PS C:\> Test-Path $x True PS C:\> cd $Env:SystemRoot\System32 PS C:\WINDOWS\System32> Get-AppInstallLocation 'Paint.NET*' -Verbose -OutVariable x | % { "[$_]" } VERBOSE: Trying local and machine (x32 & x64) Uninstall keys VERBOSE: Retrieving all uninstall registry keys VERBOSE: Trying Uninstall key property 'InstallLocation' VERBOSE: Trying Uninstall key property 'UninstallString' [MsiExec.exe ] PS C:\WINDOWS\System32> Test-Path $x True
Relative paths can be detected and rejected by calling e.g. [IO.Path]::IsPathRooted($path).

Apart from that, a simple Test-Path is not sufficient, because it does not check whether the object is a directory. It would require something like:

function Test-Directory($path) { $i = Get-Item -Path $path -ErrorAction SilentlyContinue return $i -ne $null -and $i.PSIsContainer }

There is also the matter of UninstallStrings with arguments containing path separators, which the current simplistic parsing method will not handle correctly (the trailing space is a symptom of it):

PS C:\> $location = 'MsiExec.exe /X{F10AAD91-58DF-44EC-A647-810197141667}' PS C:\> $location.Replace('"', '') | Split-Path | % { "[$_]" } [MsiExec.exe ] PS C:\> $location = '"C:\Program Files (x86)\Steam\steam.exe" steam://uninstall/7760' PS C:\> $location.Replace('"', '') | Split-Path | % { "[$_]" } [C:\Program Files (x86)\Steam\steam.exe steam:\\uninstall] PS C:\> $location = 'C:\Windows\IsUninst.exe -fE:\Gry\XComCE\Uninst.isu' PS C:\> $location.Replace('"', '') | Split-Path | % { "[$_]" } [C:\Windows\IsUninst.exe -fE:\Gry\XComCE]

https://github.com/chocolatey/chocolatey-coreteampackages/commit/555925cb5f0d3ea3ded52b9b22fb8779feae105f is enough to fix this problem with Paint.Net.

There is also the matter of UninstallStrings with arguments containing path separators, which the current simplistic parsing method will not handle correctly (the trailing space is a symptom of it).

This was made only to handle quoted single path.

I made this parsing function instead, that should return unquoted 'first argument'. It utilizes powershell parsing of arguments with some special posh chars replaced prior to iex and returned later:


    if (!(is_dir $location)) { $location = parse $location; if (is_dir $location) { return $location }}

    function parse($s) {
        $escape = "``()@;'&|><{}[]"
        [char[]]$escape | % {$i=0} { $i++; $s = $s.Replace($_, [char]$i ) }
        try { $s = iex ". { `$args[0] } $s" } catch { return $s }
        [char[]]$s | % {$r=''} { $a=[byte]$_; $r += if ( $a -le $escape.Length) { $escape[$a-1] } else {$_} }
        $r
    }

If nobody has objections I can make it into module.

@majkinetor if it's compatible with POSHv2, then there is no objection from me

I am hesitant to introduce any change to the extension since it can affect big number of packages.. The new parsing method even if better can change behavior of existing packages so all would need to be tested for it.

Since this is not actually an improvement to any existing package and I don't have time to be purist, I will just leave it be for now. If anybody else wants to give it a go feel free to do so.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kaffeekanne picture kaffeekanne  路  4Comments

verglor picture verglor  路  5Comments

AdmiringWorm picture AdmiringWorm  路  5Comments

ericoporto picture ericoporto  路  3Comments

sc250024 picture sc250024  路  3Comments