Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: German language Windows 11 - issue with Get-WGInstalled Function #8

Closed
4 of 5 tasks
SebCT opened this issue Aug 13, 2022 · 10 comments
Closed
4 of 5 tasks
Assignees
Labels
bug Something isn't working enhancement New feature or request pending pending user feedback

Comments

@SebCT
Copy link

SebCT commented Aug 13, 2022

Describe the problem

On a german language Windows 11 Installation the module will fail because of the german output of winget.

With the Function "Get-WGInstalled" on a german language Windows the winget output has to be parsed with german instead of english.

In the attached screen with "Get-WGInstalled -Verbose" you will get this result because of the german output of winget:

image

Expectation

A list of installed software with Get-WGInstalled Function.

Additional Information

I made a workaround for my german language with these lines (Line 59-69) in the Get-WGInstalled Function:

Name = $rxname.match($($show | Select-String "Gefunden\s")).value
ID = $pkg.PackageIdentifier
InstalledVersion = $installed
OnlineVersion = $online
Publisher = $(Try { (($show | Select-String "Herausgeber:") -split "Herausgeber: ")[1].trim() } Catch { $null })
PublisherURL = $(Try { (($show | Select-String "Herausgeber-Url:") -split "Herausgeber-Url: ")[1].trim() } Catch { $null })
Author = $(Try { (($show | Select-String "Autor:") -split "Autor: ")[1].trim() } Catch { $null })
Moniker = $(Try { (($show | Select-String "Moniker:") -split "Moniker: ")[1].trim() } Catch {$null })
Description = $(Try { (($show | Select-String "Beschreibung:") -split "Beschreibung: ")[1].trim() } Catch { $null })
Homepage = $(Try { (($show | Select-String "Startseite:") -split "Startseite: ")[1].trim() } Catch { $null })
Source = $Source

PowerShell version

7.2

Platform

Windows 11 Pro or Enterprise

Additional Checks

  • You are using the latest version of this module.
  • You have read this repository's README file.
  • You have read full help and examples for the command you are having problems with.
  • You are running PowerShell in an elevated session.
  • You are running in a traditional PowerShell console or Windows Terminal
@SebCT SebCT added bug Something isn't working triage new issue that needs review labels Aug 13, 2022
@SebCT SebCT changed the title [Bug]: [Bug]: German language Windows 11 - issue with Get-WGInstalled Function Aug 13, 2022
@jdhitsolutions
Copy link
Owner

I'm not too surprised there is a problem with non-English cultures. Winget doesn't leave many options to make it PowerShell-friendly and I've resorted to regex patterns which don't always translate well across cultures. I think I have another option with Get-WGInstalled I'll have to look at.

@jdhitsolutions
Copy link
Owner

I'm working on adding a YAML dependency which I think will help. I'm trying to duplicate your output. Can you run winget show gimp.gimp --source winget and paste the text output?

@SebCT
Copy link
Author

SebCT commented Aug 15, 2022

I'm working on adding a YAML dependency which I think will help. I'm trying to duplicate your output. Can you run winget show gimp.gimp --source winget and paste the text output?

Here's the output from a german OS -> winget show gimp.gimp --source winget

Gefunden GIMP [GIMP.GIMP]
Version: 2.10.32
Herausgeber: The GIMP Team
Herausgeber-Support-URL: https://docs.gimp.org/en/
Autor: The GIMP Team
Moniker: gimp
Beschreibung: GIMP is an acronym for GNU Image Manipulation Program. It is a freely distributed program for such tasks as photo retouching, image composition and image authoring.
Startseite: https://www.gimp.org
Lizenz: GPL-3.0
Lizenz-URL: https://www.gimp.org/about/COPYING
Installationsprogramm:
Typ: inno
Download-URL: https://download.gimp.org/pub/gimp/v2.10/windows/gimp-2.10.32-setup-1.exe
SHA256: e4410b5695cfc83bc2a33a124e8689a50c942978d0164e77724407d2a5cefb0d

@jdhitsolutions
Copy link
Owner

Thanks. This is what I was afraid of. Using YAML conversion still won't solve the problem. I'll need to use ConvertFrom-StringData with localized property names. It just means this will take a bit longer to resolve.

@SebCT
Copy link
Author

SebCT commented Aug 15, 2022

Thanks for trying to support german/other language, too - amazing work and a really excellent PS-Module :-)

@jdhitsolutions
Copy link
Owner

I can't find any way to duplicate the German results. But I think I have a solution. The solution requires another module dependency. I'll have to ask you to install the psyml module. This is a wrapper for the PSYamlDotNet class and I'm using it to parse winget output. Once you have the module installed, save this to a script file and run it.

#requires -version 5.1
#requires -module ThreadJob
#requires -module psyml

[cmdletbinding()]
Param([string]$ID = "microsoft.edge", [string]$Source = "winget")

$localized = ConvertFrom-StringData -StringData @"
Found               = Gefunden
Name                = Name
ID                  = ID
Version             = Version
Publisher           = Herausgeber
PublisherUrl        = Herausgeber-URL
PublisherSupportUrl = Herausgeber-Support-URL
Author              = Autor
Moniker             = Moniker
Description         = Beschreibung
Homepage            = Startseite
License             = Lizenz
LicenseURL          = Lizenz-URL
Source              = Source
Computername        = Computername
"@

Function _parseVersion {
    #parse out odd characters from version strings
    [cmdletbinding()]
    Param([string]$VersionString)

    if ($versionString -match "unknown") {
        $out = $null
    }
    elseif ($VersionString -match "[\<\>]") {
        $out = ($VersionString -replace $matches.values, "").Trim()
    }
    else {
        $out = $VersionString.Trim()
    }

    $out
}
$show = Start-ThreadJob { Param([string]$ID, [string]$source) winget show --id $id --source $source } -ArgumentList $id, $source |
Wait-Job | Receive-Job -Keep |
Where-Object { $_ -notmatch "(\d+%|\d MB|\s+)$" -and $_.length -gt 0 }

#write the winget result to the host
$show | Out-String | Write-Host -ForegroundColor cyan

Try {
    $yml = $show.replace(" - ", " ") | Select-Object -Skip 1 | Where-Object { $_ -match "^(\s+)?(\b(\w+)\b).*:" } | ConvertFrom-Yaml -ErrorAction stop
}
Catch {
    Write-Warning "Failed to convert to YAML"
    $show | Out-String | Write-Warning
}

[regex]$rxname = "(?<name>(?<=\w\s).*)(?=\s\[(?<id>[\S\.]+)\])"
$online = _parseVersion $yml.$($localized.version)
$installed = "to be determined"
[pscustomobject]@{
    PSTypeName          = "WGInstalled"
    Name                = $rxname.match($show[0]).groups["name"].value
    ID                  = $rxname.match($show[0]).groups["id"].value
    InstalledVersion    = $installed
    OnlineVersion       = $online
    Publisher           = $yml.$($localized.Publisher)
    PublisherUrl        = $yml.$($localized.PublisherURL)
    PublisherSupportUrl = $yml.$($localized.PublisherSupportUrl)
    Author              = $yml.$($localized.Author)
    Moniker             = $yml.$($localized.Moniker)
    Description         = $yml.$($localized.Description)
    Homepage            = $yml.$($Localized.homepage)
    Source              = $Source
}

I'm using a default package id, but you can try something else you have installed like gimp.gimp. I want to test localized data. The output object will still have English property names. Maybe later, I can see what it takes to create an object with localized property names.

@SebCT
Copy link
Author

SebCT commented Aug 16, 2022

I can't find any way to duplicate the German results. But I think I have a solution. The solution requires another module dependency. I'll have to ask you to install the psyml module. This is a wrapper for the PSYamlDotNet class and I'm using it to parse winget output. Once you have the module installed, save this to a script file and run it.

#requires -version 5.1
#requires -module ThreadJob
#requires -module psyml

[cmdletbinding()]
Param([string]$ID = "microsoft.edge", [string]$Source = "winget")

$localized = ConvertFrom-StringData -StringData @"
Found               = Gefunden
Name                = Name
ID                  = ID
Version             = Version
Publisher           = Herausgeber
PublisherUrl        = Herausgeber-URL
PublisherSupportUrl = Herausgeber-Support-URL
Author              = Autor
Moniker             = Moniker
Description         = Beschreibung
Homepage            = Startseite
License             = Lizenz
LicenseURL          = Lizenz-URL
Source              = Source
Computername        = Computername
"@

Function _parseVersion {
    #parse out odd characters from version strings
    [cmdletbinding()]
    Param([string]$VersionString)

    if ($versionString -match "unknown") {
        $out = $null
    }
    elseif ($VersionString -match "[\<\>]") {
        $out = ($VersionString -replace $matches.values, "").Trim()
    }
    else {
        $out = $VersionString.Trim()
    }

    $out
}
$show = Start-ThreadJob { Param([string]$ID, [string]$source) winget show --id $id --source $source } -ArgumentList $id, $source |
Wait-Job | Receive-Job -Keep |
Where-Object { $_ -notmatch "(\d+%|\d MB|\s+)$" -and $_.length -gt 0 }

#write the winget result to the host
$show | Out-String | Write-Host -ForegroundColor cyan

Try {
    $yml = $show.replace(" - ", " ") | Select-Object -Skip 1 | Where-Object { $_ -match "^(\s+)?(\b(\w+)\b).*:" } | ConvertFrom-Yaml -ErrorAction stop
}
Catch {
    Write-Warning "Failed to convert to YAML"
    $show | Out-String | Write-Warning
}

[regex]$rxname = "(?<name>(?<=\w\s).*)(?=\s\[(?<id>[\S\.]+)\])"
$online = _parseVersion $yml.$($localized.version)
$installed = "to be determined"
[pscustomobject]@{
    PSTypeName          = "WGInstalled"
    Name                = $rxname.match($show[0]).groups["name"].value
    ID                  = $rxname.match($show[0]).groups["id"].value
    InstalledVersion    = $installed
    OnlineVersion       = $online
    Publisher           = $yml.$($localized.Publisher)
    PublisherUrl        = $yml.$($localized.PublisherURL)
    PublisherSupportUrl = $yml.$($localized.PublisherSupportUrl)
    Author              = $yml.$($localized.Author)
    Moniker             = $yml.$($localized.Moniker)
    Description         = $yml.$($localized.Description)
    Homepage            = $yml.$($Localized.homepage)
    Source              = $Source
}

I'm using a default package id, but you can try something else you have installed like gimp.gimp. I want to test localized data. The output object will still have English property names. Maybe later, I can see what it takes to create an object with localized property names.

Works perfect, thanks!

image

@jdhitsolutions
Copy link
Owner

Thanks. I'll finish integrating this approach into the module.

@jdhitsolutions jdhitsolutions added enhancement New feature or request and removed triage new issue that needs review labels Aug 17, 2022
@jdhitsolutions
Copy link
Owner

I've published v1.5.0 to the PowerShell Gallery. Update the module and test in a new PowerShell session. I even added German versions of command help. Translations are from Google, so feel free to submit a PR for the German markdown files if they can be improved.

@jdhitsolutions jdhitsolutions added the pending pending user feedback label Aug 17, 2022
@SebCT
Copy link
Author

SebCT commented Aug 18, 2022

I can confirm that Version 1.5.0 is now working with german winget, too - thank you!

@SebCT SebCT closed this as completed Aug 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request pending pending user feedback
Projects
None yet
Development

No branches or pull requests

2 participants