Closed SebCT closed 2 years ago
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.
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?
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
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.
Thanks for trying to support german/other language, too - amazing work and a really excellent PS-Module :-)
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.
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!
Thanks. I'll finish integrating this approach into the module.
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.
I can confirm that Version 1.5.0 is now working with german winget, too - thank you!
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:
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