From abbd4e1b346df82f66edc8312289c9e13303d837 Mon Sep 17 00:00:00 2001 From: James Tarran Date: Mon, 21 Sep 2026 09:23:31 +0100 Subject: [PATCH] Correlate installed software the way winget does Detection had grown four name heuristics - exact, bounded prefix, substring and MSIX name - because it was reverse engineering "is this package installed" from the registry. Each new application found another gap, and the last one, Microsoft.Office, caused a reinstall loop on a production endpoint. winget does not guess. Its list path is an exact-equality join on four keys, OR'd together: PackageFamilyName, ProductCode, UpgradeCode and NormalizedNameAndPublisher (CompositeSource.cpp:937). There is no fuzzy matching in it at all. The edit-distance code in ARPCorrelation.cpp is the post-install heuristic and is deliberately not ported. The winget source index already carries all four, and we were shipping two. It now ships all four, including norm_names2 and norm_publishers2, which is the only key that covers the 6,443 packages declaring no identifier at all. Every one of the 14,896 packages has a normalised name and publisher, so name correlation is total rather than a fallback. Get-WgNormalized is a port of NormalizationVersion::Initial from NameNormalization.cpp. The subtle part is that ICU applies case closure to character classes under UREGEX_CASE_INSENSITIVE and .NET does not, so every \p{Lu} is written out as [\p{Lu}\p{Ll}\p{Lt}]. Without that the locale pattern never fires and "Microsoft 365 Apps for enterprise - en-us" does not reduce to the stored key. A name match requires a publisher match, as winget's inner join does. That is why Git.Git cannot collide with GitHub CLI without any boundary rule, and it removes the need for the prefix heuristic entirely. Weak matches on a name+publisher pair shared by several packages are dropped, reproducing the reverse-correlation veto. Packages carrying a real identifier are unaffected because a strong match returns first: Google Chrome shares its pair with Google.Chrome.EXE and still resolves, on UpgradeCode. UpgradeCode needs a second registry read. It is not a value on the uninstall key but lives under Installer\UpgradeCodes in packed GUID form, keyed the opposite way round, so the map is built once and inverted. Tests, because every defect this replaces reached an endpoint before anyone noticed. Tests/Test-Normalizer.ps1 runs winget's own 1,137 vector corpus, vendored under Tests/corpus, plus the architecture anchors from its unit tests. Tests/Test-Module.ps1 covers the structural faults that have actually happened here: a scope qualifier that stopped the module loading, an exported function with no file, and a control character that made a workflow unparseable. Both run on every pull request. Verified against "winget list --id X --exact" for all 61 packages installed on a real machine: 61/61 agreement, by ProductCode 32, PackageFamilyName 19, NameAndPublisher 7, UpgradeCode 2. That includes agreeing that Bitwarden.Bitwarden is NOT detectable, which winget also reports, because it has no ARP entry and no MSIX package. --- .github/workflows/build-manifest-index.yml | 52 +- .github/workflows/ci.yml | 20 + Private/Get-ArpEntry.ps1 | 172 +++ Private/Get-DetectionIndex.ps1 | 37 +- Private/Get-WgNormalized.ps1 | 244 +++++ Public/Test-TecharyApp.ps1 | 342 +++--- Tests/Test-Module.ps1 | 62 ++ Tests/Test-Normalizer.ps1 | 86 ++ Tests/corpus/InputNames.txt | 1137 ++++++++++++++++++++ Tests/corpus/InputPublishers.txt | 1137 ++++++++++++++++++++ Tests/corpus/NormalizationInitialIds.txt | 1137 ++++++++++++++++++++ Tests/corpus/README.md | 6 + 12 files changed, 4215 insertions(+), 217 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 Private/Get-ArpEntry.ps1 create mode 100644 Private/Get-WgNormalized.ps1 create mode 100644 Tests/Test-Module.ps1 create mode 100644 Tests/Test-Normalizer.ps1 create mode 100644 Tests/corpus/InputNames.txt create mode 100644 Tests/corpus/InputPublishers.txt create mode 100644 Tests/corpus/NormalizationInitialIds.txt create mode 100644 Tests/corpus/README.md diff --git a/.github/workflows/build-manifest-index.yml b/.github/workflows/build-manifest-index.yml index ddaaf15..70cda85 100644 --- a/.github/workflows/build-manifest-index.yml +++ b/.github/workflows/build-manifest-index.yml @@ -58,40 +58,74 @@ jobs: # but the entry still carries the canonical display name, and that is # what bridges an ID to its ARP entry: "Valve.Steam" never matches # "Steam" on its own. A name-only row costs about 80 bytes. + # Kinds: P product code, F package family name, M normalised name, + # B normalised publisher, N name-only placeholder. + # + # M and B are winget's OWN correlation keys, from norm_names2 and + # norm_publishers2. They are what makes this work for the 6,443 + # packages that declare no product code and no package family name + # -- Microsoft.Office among them. A name match is only valid when a + # publisher matches too, so both must ship. sqlite3 "$DB" -json " SELECT p.id AS Id, p.name AS Name, p.latest_version AS Version, 'P' AS Kind, c.productcode AS Value FROM packages p JOIN productcodes2 c ON c.package = p.rowid UNION ALL - SELECT p.id, p.name, p.latest_version, - 'F', f.pfn + SELECT p.id, p.name, p.latest_version, 'F', f.pfn FROM packages p JOIN pfns2 f ON f.package = p.rowid UNION ALL - SELECT p.id, p.name, p.latest_version, - 'N', NULL + SELECT p.id, p.name, p.latest_version, 'M', n.norm_name + FROM packages p JOIN norm_names2 n ON n.package = p.rowid + UNION ALL + SELECT p.id, p.name, p.latest_version, 'B', b.norm_publisher + FROM packages p JOIN norm_publishers2 b ON b.package = p.rowid + UNION ALL + SELECT p.id, p.name, p.latest_version, 'U', u.upgradecode + FROM packages p JOIN upgradecodes2 u ON u.package = p.rowid + UNION ALL + SELECT p.id, p.name, p.latest_version, 'N', NULL FROM packages p - WHERE NOT EXISTS (SELECT 1 FROM productcodes2 WHERE package = p.rowid) - AND NOT EXISTS (SELECT 1 FROM pfns2 WHERE package = p.rowid) ORDER BY 1;" > pairs.json + # Name+publisher pairs carried by more than one package. winget + # resolves these with a reverse-correlation veto; without the full + # reverse index we suppress the weak match instead, which is the + # safe direction. mozillathunderbird+mozilla alone is shared by 133 + # package ids, so skipping this over-reports badly. + sqlite3 "$DB" -json " + SELECT n.norm_name AS N, b.norm_publisher AS B, COUNT(DISTINCT p.rowid) AS C + FROM packages p + JOIN norm_names2 n ON n.package = p.rowid + JOIN norm_publishers2 b ON b.package = p.rowid + GROUP BY n.norm_name, b.norm_publisher + HAVING COUNT(DISTINCT p.rowid) > 1;" > ambiguous.json + NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ) - jq --arg now "$NOW" ' + jq --arg now "$NOW" --slurpfile amb ambiguous.json ' group_by(.Id) | map({ key: .[0].Id, value: { Name: .[0].Name, Version: .[0].Version, - ProductCodes: [ .[] | select(.Kind == "P") | .Value ], - Pfns: [ .[] | select(.Kind == "F") | .Value ] + ProductCodes: [ .[] | select(.Kind == "P") | .Value ], + Pfns: [ .[] | select(.Kind == "F") | .Value ], + NormNames: [ .[] | select(.Kind == "M") | .Value ], + NormPublishers: [ .[] | select(.Kind == "B") | .Value ], + UpgradeCodes: [ .[] | select(.Kind == "U") | .Value ] }}) | from_entries | { Generated: $now, Source: "winget source2 index", + Normalizer: "Initial", PackageCount: length, + AmbiguousPairs: ( $amb[0] | map(.N + "|" + .B) ), Packages: . } ' pairs.json > Index/Detection.json + echo "ambiguous name+publisher pairs: $(jq -r '.AmbiguousPairs | length' Index/Detection.json)" + echo "packages with a norm name: $(jq -r '[.Packages[] | select(.NormNames | length > 0)] | length' Index/Detection.json)" + echo "detection index: $(jq -r .PackageCount Index/Detection.json) packages, $(du -h Index/Detection.json | cut -f1)" # --------------------------------------------------------------- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b56f01f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +jobs: + test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Structural checks + shell: pwsh + run: ./Tests/Test-Module.ps1 + + - name: Name normaliser against winget's own corpus + shell: pwsh + run: ./Tests/Test-Normalizer.ps1 diff --git a/Private/Get-ArpEntry.ps1 b/Private/Get-ArpEntry.ps1 new file mode 100644 index 0000000..383bce1 --- /dev/null +++ b/Private/Get-ArpEntry.ps1 @@ -0,0 +1,172 @@ +function Get-ArpEntry { + <# + .SYNOPSIS + The machine's Add/Remove Programs entries, enumerated as winget does. + + .DESCRIPTION + Mirrors ARPHelper::PopulateIndexFromARP. Three views, and the skip + rules matter: a divergence here means our inventory differs from + winget's before any matching happens. + + machine HKLM\...\Uninstall 64-bit view + machine HKLM\WOW6432Node\...\Uninstall 32-bit view + user HKCU\...\Uninstall native view only + + There is deliberately no 32-bit view for user scope -- the + KEY_WOW64_32KEY branch is gated on machine scope (ARPHelper.cpp:167). + + ProductCode is the SUBKEY NAME, not a value (ARPHelper.cpp:396). + + Note the skip rules are exactly three. The source also appears to + skip entries with no version, but DetermineVersion returns + "Unknown" rather than empty, so that branch never fires; adding it + here would drop entries winget keeps. + #> + [CmdletBinding()] + param() + + $Hives = @( + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' + ) + + foreach ($Hive in $Hives) { + foreach ($Key in (Get-ChildItem -LiteralPath $Hive -ErrorAction SilentlyContinue)) { + $Item = $null + try { $Item = Get-ItemProperty -LiteralPath $Key.PSPath -ErrorAction Stop } catch { continue } + + # 1. SystemComponent non-zero + if ($Item.PSObject.Properties['SystemComponent'] -and [int]$Item.SystemComponent -ne 0) { continue } + # 2 and 3. DisplayName absent, or empty + $Display = $Item.PSObject.Properties['DisplayName'] | ForEach-Object { $_.Value } + if ([string]::IsNullOrEmpty($Display)) { continue } + + $Publisher = $null + if ($Item.PSObject.Properties['Publisher']) { $Publisher = [string]$Item.Publisher } + + # UpgradeCode is only looked up for MSI entries (ARPHelper.cpp:472). + $IsMsi = $false + if ($Item.PSObject.Properties['WindowsInstaller']) { + try { $IsMsi = ([int]$Item.WindowsInstaller -ne 0) } catch { } + } + + [PSCustomObject]@{ + ProductCode = $Key.PSChildName + DisplayName = [string]$Display + Publisher = $Publisher + DisplayVersion = $(if ($Item.PSObject.Properties['DisplayVersion']) { [string]$Item.DisplayVersion } else { $null }) + WindowsInstaller = $IsMsi + Path = $Key.PSPath + } + } + } +} + +function ConvertTo-PackedGuid { + <# + MSI's packed GUID form: the first three groups are reversed whole, + the last two are reversed bytewise. ARPHelper.cpp:15-60. + #> + param([Parameter(Mandatory)][string]$Guid) + $g = $Guid.Trim().Trim('{', '}') + $p = $g.Split('-') + if ($p.Count -ne 5) { return $null } + $r = ($p[0][7,6,5,4,3,2,1,0] -join '') + $r += ($p[1][3,2,1,0] -join '') + $r += ($p[2][3,2,1,0] -join '') + $r += ($p[3][1,0] -join '') + ($p[3][3,2] -join '') + for ($i = 0; $i -lt 12; $i += 2) { $r += ($p[4][($i + 1), $i] -join '') } + return $r.ToUpperInvariant() +} + +function ConvertFrom-PackedGuid { + param([Parameter(Mandatory)][string]$Packed) + if ($Packed.Length -ne 32) { return $null } + $a = ($Packed[7,6,5,4,3,2,1,0] -join '') + $b = ($Packed[11,10,9,8] -join '') + $c = ($Packed[15,14,13,12] -join '') + $d = ($Packed[17,16] -join '') + ($Packed[19,18] -join '') + $e = '' + for ($i = 20; $i -lt 32; $i += 2) { $e += ($Packed[($i + 1), $i] -join '') } + return ('{{{0}-{1}-{2}-{3}-{4}}}' -f $a, $b, $c, $d, $e).ToLowerInvariant() +} + +function Get-UpgradeCodeMap { + <# + .SYNOPSIS + Packed product code -> upgrade code, for MSI entries. + + .DESCRIPTION + UpgradeCode is not a value on the uninstall key. It lives under + Installer\UpgradeCodes keyed the opposite way round: the key name is + the packed upgrade code and its VALUES are the packed product codes + it covers (ARPHelper.cpp:63-105). Built once and inverted, because + walking it per entry would be far slower. + + There is no UpgradeCodes key in the 32-bit view (ARPHelper.cpp:82). + #> + [CmdletBinding()] + param() + + $Map = @{} + $Root = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes' + foreach ($Key in (Get-ChildItem -LiteralPath $Root -ErrorAction SilentlyContinue)) { + $Upgrade = ConvertFrom-PackedGuid $Key.PSChildName + if (-not $Upgrade) { continue } + $Props = $null + try { $Props = Get-ItemProperty -LiteralPath $Key.PSPath -ErrorAction Stop } catch { continue } + foreach ($p in $Props.PSObject.Properties) { + if ($p.Name -like 'PS*') { continue } + if (-not $Map.ContainsKey($p.Name)) { $Map[$p.Name] = $Upgrade } + } + } + return $Map +} + +function Get-ArpCorrelationSet { + <# + .SYNOPSIS + ARP entries with winget's correlation keys precomputed. + + .DESCRIPTION + Normalising every entry costs real time, so this is done once per + call to Test-TecharyApp rather than once per candidate key. + #> + [CmdletBinding()] + param() + + $Upgrades = @{} + try { $Upgrades = Get-UpgradeCodeMap } catch { } + + foreach ($e in Get-ArpEntry) { + $n = $null + try { $n = Get-WgNormalizedName -Name $e.DisplayName } catch { } + if (-not $n) { continue } + + $upgrade = $null + if ($e.WindowsInstaller) { + $packed = ConvertTo-PackedGuid $e.ProductCode + if ($packed -and $Upgrades.ContainsKey($packed)) { $upgrade = $Upgrades[$packed] } + } + + # Both forms: winget stores an extra arch-suffixed row for ARP + # display names, and matches against whichever the package carries. + $names = [Collections.Generic.List[string]]::new() + if ($n.Name) { $names.Add($n.Name) } + $withArch = Get-WgNameWithArchitecture $n + if ($withArch -and $withArch -ne $n.Name) { $names.Add($withArch) } + + $pub = '' + if (-not [string]::IsNullOrEmpty($e.Publisher)) { + try { $pub = Get-WgNormalizedPublisher -Publisher $e.Publisher } catch { $pub = '' } + } + + [PSCustomObject]@{ + Entry = $e + UpgradeCode = $upgrade + NormNames = $names + NormPublisher = $pub + } + } +} diff --git a/Private/Get-DetectionIndex.ps1 b/Private/Get-DetectionIndex.ps1 index 327c8e9..c2cec9a 100644 --- a/Private/Get-DetectionIndex.ps1 +++ b/Private/Get-DetectionIndex.ps1 @@ -82,10 +82,37 @@ function Get-DetectionEntry { if (-not $Entry) { return $null } return [PSCustomObject]@{ - Id = $Id - Name = $Entry.Name - Version = $Entry.Version - ProductCodes = @($Entry.ProductCodes) - Pfns = @($Entry.Pfns) + Id = $Id + Name = $Entry.Name + Version = $Entry.Version + ProductCodes = @($Entry.ProductCodes) + Pfns = @($Entry.Pfns) + UpgradeCodes = @($Entry.UpgradeCodes) + NormNames = @($Entry.NormNames) + NormPublishers = @($Entry.NormPublishers) } } + +function Get-AmbiguousPairSet { + <# + .SYNOPSIS + Name+publisher pairs carried by more than one package. + + .DESCRIPTION + winget drops a weak name match when the installed entry correlates to + more than one available package. Reproducing that faithfully needs a + full reverse index; this is the cheap half of it. Suppressing the + match is the safe direction: mozillathunderbird+mozilla is shared by + 133 package ids, so one Thunderbird entry would otherwise report all + 133 as installed. + #> + [CmdletBinding()] + param([switch]$NoRefresh) + + $Index = Get-DetectionIndex -NoRefresh:$NoRefresh + $Set = [Collections.Generic.HashSet[string]]::new([StringComparer]::Ordinal) + if ($Index -and $Index.AmbiguousPairs) { + foreach ($p in $Index.AmbiguousPairs) { if ($p) { [void]$Set.Add($p) } } + } + return $Set +} diff --git a/Private/Get-WgNormalized.ps1 b/Private/Get-WgNormalized.ps1 new file mode 100644 index 0000000..b7cf0ee --- /dev/null +++ b/Private/Get-WgNormalized.ps1 @@ -0,0 +1,244 @@ +# ====================================================================== +# A port of winget's NormalizationVersion::Initial name and publisher +# normaliser, from src/AppInstallerCommonCore/NameNormalization.cpp. +# +# The values in the winget source index's norm_names2 and norm_publishers2 +# are produced by this algorithm applied to case-folded input. Reproducing +# it lets us correlate an installed ARP entry to a winget package exactly +# as winget does, instead of guessing with name heuristics. +# +# Validated against winget's own 1137-row test corpus. +# ====================================================================== + +$Script:RxOpt = [Text.RegularExpressions.RegexOptions]'IgnoreCase, CultureInvariant, Compiled' +function New-Rx { param([string]$P) [regex]::new($P, $Script:RxOpt) } + +# ICU applies UREGEX_CASE_INSENSITIVE, which case-CLOSES character classes, +# so \p{Lu} also matches lowercase. .NET's IgnoreCase does not do that, so +# every \p{Lu} below is written out as [\p{Lu}\p{Ll}\p{Lt}]. \p{L} would be +# wrong: it adds \p{Lo} (CJK, Hebrew, Arabic), which ICU's closure does not. +$LU = '[\p{Lu}\p{Ll}\p{Lt}]' + +# --- architecture (NameNormalization.cpp:243-247) --------------------- +$Script:RxArch32Or64 = New-Rx '(?<=^|[^\p{L}\p{Nd}])((64[\\\/]32|32[\\\/]64)[\p{Pd}\p{Pc}\p{Z}]?BIT)S?(?:\sEDITION)?' +$Script:RxArchX64 = New-Rx '(?<=^|[^\p{L}\p{Nd}])(X64|AMD64|X86([\p{Pd}\p{Pc}]64))(?=\P{Nd}|$)(?:\sEDITION)?' +$Script:RxArch64Bit = New-Rx '(?<=^|[^\p{L}\p{Nd}])(64[\p{Pd}\p{Pc}\p{Z}]?BIT)S?(?:\sEDITION)?' +$Script:RxArchX32 = New-Rx '(?<=^|[^\p{L}\p{Nd}])(X32|X86)(?=\P{Nd}|$)(?:\sEDITION)?' +$Script:RxArch32Bit = New-Rx '(?<=^|[^\p{L}\p{Nd}])(32[\p{Pd}\p{Pc}\p{Z}]?BIT)S?(?:\sEDITION)?' + +# --- locale / SAP / KB (:250, :253, KB at :387) ----------------------- +# Both [A-Z] lookarounds become [A-Za-z] as well as the \p{Lu} rewrite. +# Without both, "… - en-us" never matches and the Office case fails. +$Script:RxLocale = New-Rx ("(? [CmdletBinding()] - param ( + param( [Parameter(Mandatory=$true)] [string]$Name, [switch]$Detailed ) - $Hives = @( - "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", - "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall", - "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall" - ) - function New-Result { param($Installed, $MatchedBy, $DisplayName, $Version, $Key) [PSCustomObject]@{ @@ -54,217 +51,156 @@ function Test-TecharyApp { } } - if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { $SysArch = "arm64" } - elseif ([Environment]::Is64BitOperatingSystem) { $SysArch = "x64" } - else { $SysArch = "x86" } + if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') { $SysArch = 'arm64' } + elseif ([Environment]::Is64BitOperatingSystem) { $SysArch = 'x64' } + else { $SysArch = 'x86' } - # --- 1. PRODUCT CODE / PACKAGE FAMILY (definitive) ----------------- - # Three sources, most complete first: the full detection index covers - # every package in the winget repository; the curated manifest index and - # the local manifest cache cover what this machine has installed before. - $ProductCodes = New-Object System.Collections.Generic.List[string] - $Pfns = New-Object System.Collections.Generic.List[string] + $Entry = $null + try { $Entry = Get-DetectionEntry -Id $Name -NoRefresh } catch { } - try { - $Entry = Get-DetectionEntry -Id $Name -NoRefresh - if ($Entry) { - foreach ($Code in $Entry.ProductCodes) { if ($Code) { $ProductCodes.Add($Code) } } - foreach ($Family in $Entry.Pfns) { if ($Family) { $Pfns.Add($Family) } } - Write-Verbose "Detection index: $($ProductCodes.Count) product code(s), $($Pfns.Count) package family name(s) for '$Name'" - } - } catch {} + # Normalising every ARP entry is the expensive part, so it is done once. + $Arp = @(Get-ArpCorrelationSet) - try { - $Indexed = Get-IndexedManifest -Id $Name -SysArch $SysArch -NoRefresh - if ($Indexed -and $Indexed.ProductCode) { $ProductCodes.Add($Indexed.ProductCode) } - } catch {} + # ---- 1. STRONG IDENTIFIERS -------------------------------------- + $Codes = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) + $Pfns = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) + $Upgrades = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) + + if ($Entry) { + foreach ($c in $Entry.ProductCodes) { if ($c) { [void]$Codes.Add($c) } } + foreach ($f in $Entry.Pfns) { if ($f) { [void]$Pfns.Add($f) } } + foreach ($u in $Entry.UpgradeCodes) { if ($u) { [void]$Upgrades.Add($u) } } + } - $CachedManifest = Join-Path $env:ProgramData ("TecharyGet\ManifestCache\" + ($Name -replace '[\\/:*?"<>|]', '_') + ".json") - if (Test-Path $CachedManifest) { + # A manifest resolved on this machine earlier also carries a product code. + $Cached = Join-Path $env:ProgramData ("TecharyGet\ManifestCache\" + ($Name -replace '[\\/:*?"<>|]', '_') + ".json") + if (Test-Path $Cached) { try { - $Local = (Get-Content $CachedManifest -Raw | ConvertFrom-Json).ProductCode - if ($Local) { $ProductCodes.Add($Local) } - } catch {} + $c = (Get-Content $Cached -Raw | ConvertFrom-Json).ProductCode + if ($c) { [void]$Codes.Add($c) } + } catch { } } - if ($ProductCodes.Count -gt 0) { - # Enumerate the machine's uninstall key NAMES once and hash-look-up each - # candidate, rather than probing the registry per code. - # - # The winget source carries every product code a package has ever - # shipped: Mozilla.Firefox alone has 5205, one per locale and version. - # Probing those across three hives is 15,615 registry reads and took - # ~384 seconds measured, which would exceed an N-central scan interval - # on its own. This is ~230 reads regardless of how many codes a package - # has. Ordinal-ignore-case because the index stores codes normalised to - # lower case ("7-zip") while the real key is "7-Zip", and the registry - # itself is case-insensitive. - $ArpKeys = New-Object 'System.Collections.Generic.Dictionary[string,string]' ([StringComparer]::OrdinalIgnoreCase) - foreach ($Hive in $Hives) { - foreach ($Key in (Get-ChildItem -Path $Hive -ErrorAction SilentlyContinue)) { - if (-not $ArpKeys.ContainsKey($Key.PSChildName)) { $ArpKeys[$Key.PSChildName] = $Key.PSPath } - } + foreach ($a in $Arp) { + if ($Codes.Count -gt 0 -and $Codes.Contains($a.Entry.ProductCode)) { + Write-Verbose "ProductCode '$($a.Entry.ProductCode)'" + $R = New-Result $true 'ProductCode' $a.Entry.DisplayName $a.Entry.DisplayVersion $a.Entry.Path + if ($Detailed) { return $R } else { return $true } } - - foreach ($Code in $ProductCodes) { - $Path = $null - if ($ArpKeys.TryGetValue($Code, [ref]$Path)) { - $Item = Get-ItemProperty -Path $Path -ErrorAction SilentlyContinue - Write-Verbose "Matched on ProductCode '$Code' at $Path" - $R = New-Result $true 'ProductCode' $Item.DisplayName $Item.DisplayVersion $Path - if ($Detailed) { return $R } else { return $true } - } + if ($Upgrades.Count -gt 0 -and $a.UpgradeCode -and $Upgrades.Contains($a.UpgradeCode)) { + Write-Verbose "UpgradeCode '$($a.UpgradeCode)'" + $R = New-Result $true 'UpgradeCode' $a.Entry.DisplayName $a.Entry.DisplayVersion $a.Entry.Path + if ($Detailed) { return $R } else { return $true } } } if ($Pfns.Count -gt 0) { $Elevated = $false try { - $Ident = [Security.Principal.WindowsIdentity]::GetCurrent() - $Elevated = (New-Object Security.Principal.WindowsPrincipal($Ident)).IsInRole( + $Id = [Security.Principal.WindowsIdentity]::GetCurrent() + $Elevated = (New-Object Security.Principal.WindowsPrincipal($Id)).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator) - } catch {} - + } catch { } try { - # -AllUsers when we can: SYSTEM sees almost none of its own packages. - if ($Elevated) { $Installed = @(Get-AppxPackage -AllUsers -ErrorAction Stop) } - else { $Installed = @(Get-AppxPackage -ErrorAction SilentlyContinue) } - - foreach ($Family in $Pfns) { - $Hit = $Installed | Where-Object { $_.PackageFamilyName -eq $Family } | Select-Object -First 1 - if ($Hit) { - Write-Verbose "Matched on PackageFamilyName '$Family'" - $R = New-Result $true 'PackageFamilyName' $Hit.Name $Hit.Version $Hit.PackageFullName + # -AllUsers when we can: SYSTEM sees almost none of its own. + $Pkgs = if ($Elevated) { @(Get-AppxPackage -AllUsers -ErrorAction Stop) } + else { @(Get-AppxPackage -ErrorAction SilentlyContinue) } + foreach ($p in $Pkgs) { + if ($Pfns.Contains($p.PackageFamilyName)) { + Write-Verbose "PackageFamilyName '$($p.PackageFamilyName)'" + $R = New-Result $true 'PackageFamilyName' $p.Name $p.Version $p.PackageFullName if ($Detailed) { return $R } else { return $true } } } - } catch {} + } catch { } } - # --- 2. EXACT DISPLAY NAME ---------------------------------------- - # A custom catalogue entry carries the real ARP DisplayName for its ID. - # Two lists, because a name safe to compare exactly is not safe to compare - # as a substring. - # - # The detection index carries each package's canonical display name, which - # is what bridges an ID to its ARP entry: "Google.Chrome" never matches - # "Google Chrome" on its own, and product codes alone do not cover it - # because Chrome's installed code varies by build. - # - # Those names are short and generic, so they are used for exact comparison - # ONLY. Feeding them to the substring tier reports anything that merely - # contains them: "Steam" matches the MSIX package "MSTeams", and "Git" - # matches "GitHub CLI". Both were observed. - $ExactCandidates = New-Object System.Collections.Generic.List[string] - $LooseCandidates = New-Object System.Collections.Generic.List[string] - - $ExactCandidates.Add($Name) - $LooseCandidates.Add($Name) - - try { - $CustomApp = Get-CustomApp -Id $Name -NoRefresh - if ($CustomApp -and $CustomApp.DisplayName) { - $ExactCandidates.Add($CustomApp.DisplayName) - $LooseCandidates.Add($CustomApp.DisplayName) - } - } catch {} - - if ($Entry -and $Entry.Name) { $ExactCandidates.Add($Entry.Name) } - - $AllArp = foreach ($Hive in $Hives) { - Get-ItemProperty -Path (Join-Path $Hive '*') -ErrorAction SilentlyContinue - } - - foreach ($Candidate in $ExactCandidates) { - $Exact = $AllArp | Where-Object { $_.DisplayName -eq $Candidate } | Select-Object -First 1 - if ($Exact) { - Write-Verbose "Matched exactly on DisplayName '$Candidate'" - $R = New-Result $true 'ExactName' $Exact.DisplayName $Exact.DisplayVersion $Exact.PSPath - if ($Detailed) { return $R } else { return $true } - } - } - - # --- 2b. CANONICAL NAME AS A BOUNDED PREFIX ----------------------- - # ARP routinely appends a locale or version to the product name, so an - # exact comparison misses by a few characters: - # - # index Microsoft.Office -> "Microsoft 365 Apps for enterprise" - # ARP "Microsoft 365 Apps for enterprise - en-us" - # - # Detection returned False forever for Office, which in a self-healing - # pair means the install policy reinstalls it on every scan. - # - # A plain substring match would fix that and reintroduce the false - # positives tier 3 is restricted to avoid. The rule that satisfies both is - # a prefix that ends on a token boundary: the entry must START with the - # candidate, and the next character must not be alphanumeric. - # - # "Microsoft 365 Apps for enterprise - en-us" next char " " -> match - # "7-Zip 26.03 (x64)" vs "7-Zip" next char " " -> match - # "GitHub CLI" vs "Git" next char "H" -> no - # "MSTeams" vs "Steam" not a prefix -> no - foreach ($Candidate in $ExactCandidates) { - if ([string]::IsNullOrWhiteSpace($Candidate)) { continue } - - $Bounded = $AllArp | Where-Object { - $Display = $_.DisplayName - if ([string]::IsNullOrEmpty($Display)) { return $false } - if (-not $Display.StartsWith($Candidate, [StringComparison]::OrdinalIgnoreCase)) { return $false } - if ($Display.Length -eq $Candidate.Length) { return $true } - -not [char]::IsLetterOrDigit($Display[$Candidate.Length]) - } | Select-Object -First 1 + # ---- 2. NORMALISED NAME AND PUBLISHER --------------------------- + if ($Entry -and $Entry.NormNames.Count -gt 0 -and $Entry.NormPublishers.Count -gt 0) { + + # Architecture override: if the package carries any arch-suffixed + # name, ONLY those are used. Winget erases the plain filters rather + # than falling back to them (Interface_2_0.cpp:483). + $ArchNames = @($Entry.NormNames | Where-Object { $_ -match '\((X64|X86)\)$' }) + $Query = if ($ArchNames.Count -gt 0) { $ArchNames } else { @($Entry.NormNames) } + + $QuerySet = [Collections.Generic.HashSet[string]]::new([StringComparer]::Ordinal) + foreach ($q in $Query) { if ($q) { [void]$QuerySet.Add($q) } } + + $PubSet = [Collections.Generic.HashSet[string]]::new([StringComparer]::Ordinal) + foreach ($p in $Entry.NormPublishers) { if ($p) { [void]$PubSet.Add($p) } } + + $Ambiguous = $null + try { $Ambiguous = Get-AmbiguousPairSet -NoRefresh } catch { } + + foreach ($a in $Arp) { + # An entry with no publisher can never match by name: the filters + # are a cartesian product of names x publishers, and an empty + # publisher list yields nothing. + if ([string]::IsNullOrEmpty($a.NormPublisher)) { continue } + if (-not $PubSet.Contains($a.NormPublisher)) { continue } + + foreach ($n in $a.NormNames) { + if ([string]::IsNullOrEmpty($n)) { continue } + if (-not $QuerySet.Contains($n)) { continue } + + # Reverse-correlation veto: winget drops a weak match when the + # installed entry correlates to more than one available + # package (CompositeSource.cpp:1651). A shared name+publisher + # pair is exactly that case -- mozillathunderbird+mozilla is + # carried by 133 package ids, and without this one Thunderbird + # entry reports all 133 as installed. + # + # Packages with a real identifier are unaffected: a strong + # match returns above and is never vetoed. That is how Google + # Chrome still resolves despite sharing its pair with + # Google.Chrome.EXE -- it matches on UpgradeCode first. + if ($Ambiguous -and $Ambiguous.Contains($n + '|' + $a.NormPublisher)) { + Write-Verbose "Vetoed: '$n' + '$($a.NormPublisher)' is shared by more than one package" + continue + } - if ($Bounded) { - Write-Verbose "Matched '$Candidate' as a bounded prefix of '$($Bounded.DisplayName)'" - $R = New-Result $true 'NamePrefix' $Bounded.DisplayName $Bounded.DisplayVersion $Bounded.PSPath - if ($Detailed) { return $R } else { return $true } + Write-Verbose "NormalizedNameAndPublisher '$n' + '$($a.NormPublisher)'" + $R = New-Result $true 'NameAndPublisher' $a.Entry.DisplayName $a.Entry.DisplayVersion $a.Entry.Path + if ($Detailed) { return $R } else { return $true } + } } } - # --- 3. SUBSTRING (imprecise, kept for compatibility) ------------- - # Loose list only. A canonical name from the index is too generic to - # widen with wildcards. - foreach ($Candidate in $LooseCandidates) { - # Escaped: an unescaped name containing [ or ] is a wildcard pattern, - # which previously made the comparison silently match nothing. - $Pattern = "*" + [System.Management.Automation.WildcardPattern]::Escape($Candidate) + "*" - $Loose = $AllArp | Where-Object { $_.DisplayName -like $Pattern } | Select-Object -First 1 - if ($Loose) { - Write-Verbose "Matched '$Candidate' only as a substring of '$($Loose.DisplayName)'. This is imprecise; add the package to the manifest index for an exact ProductCode match." - $R = New-Result $true 'Substring' $Loose.DisplayName $Loose.DisplayVersion $Loose.PSPath - if ($Detailed) { return $R } else { return $true } + # ---- 3. CUSTOM CATALOGUE ---------------------------------------- + # Applications that are not winget packages have no index entry, so + # correlation cannot help. Their catalogue DisplayName is authoritative. + $CustomName = $null + try { + $Custom = Get-CustomApp -Id $Name -NoRefresh + if ($Custom -and $Custom.DisplayName) { $CustomName = $Custom.DisplayName } + } catch { } + + foreach ($candidate in @($CustomName, $Name)) { + if ([string]::IsNullOrWhiteSpace($candidate)) { continue } + foreach ($a in $Arp) { + if ($a.Entry.DisplayName -eq $candidate) { + Write-Verbose "Exact display name '$candidate'" + $R = New-Result $true 'ExactName' $a.Entry.DisplayName $a.Entry.DisplayVersion $a.Entry.Path + if ($Detailed) { return $R } else { return $true } + } } } - # --- 4. MSIX ------------------------------------------------------ - # SYSTEM sees almost no packages of its own, so enumerate for all users - # when we are able to. - $IsElevated = $false - try { - $Identity = [Security.Principal.WindowsIdentity]::GetCurrent() - $IsElevated = (New-Object Security.Principal.WindowsPrincipal($Identity)).IsInRole( - [Security.Principal.WindowsBuiltInRole]::Administrator) - } catch {} - - # Loose list only, for the same reason: "Steam" as a wildcard matches the - # MSIX package MSTeams, which was reported as Valve.Steam being installed - # on a machine that has never had it. - foreach ($Candidate in $LooseCandidates) { - $Pattern = "*" + [System.Management.Automation.WildcardPattern]::Escape($Candidate) + "*" - $Msix = $null + # ---- 4. MSIX BY NAME -------------------------------------------- + foreach ($candidate in @($CustomName, $Name)) { + if ([string]::IsNullOrWhiteSpace($candidate)) { continue } + $Pattern = '*' + [Management.Automation.WildcardPattern]::Escape($candidate) + '*' try { - if ($IsElevated) { $Msix = Get-AppxPackage -AllUsers -Name $Pattern -ErrorAction SilentlyContinue | Select-Object -First 1 } - if (-not $Msix) { $Msix = Get-AppxPackage -Name $Pattern -ErrorAction SilentlyContinue | Select-Object -First 1 } - } catch {} - - if ($Msix) { - Write-Verbose "Matched MSIX package '$($Msix.Name)'" - $R = New-Result $true 'Msix' $Msix.Name $Msix.Version $Msix.PackageFullName - if ($Detailed) { return $R } else { return $true } - } + $Msix = Get-AppxPackage -Name $Pattern -ErrorAction SilentlyContinue | Select-Object -First 1 + if ($Msix) { + Write-Verbose "MSIX '$($Msix.Name)'" + $R = New-Result $true 'Msix' $Msix.Name $Msix.Version $Msix.PackageFullName + if ($Detailed) { return $R } else { return $true } + } + } catch { } } - # --- 5. NOT FOUND ------------------------------------------------- $R = New-Result $false 'None' $null $null $null if ($Detailed) { return $R } else { return $false } } diff --git a/Tests/Test-Module.ps1 b/Tests/Test-Module.ps1 new file mode 100644 index 0000000..b385ef9 --- /dev/null +++ b/Tests/Test-Module.ps1 @@ -0,0 +1,62 @@ +<# +.SYNOPSIS + Structural checks that every change to this module must pass. + +.DESCRIPTION + Each of these corresponds to a defect that reached a production endpoint + because nothing checked for it: + + parse - a stray scope qualifier stopped the module loading + manifest - FunctionsToExport advertised a function with no file + import - a file that failed to dot-source took its functions + with it, surfacing later as "command not found" + exports - the manifest and the files on disk disagreed + encoding - a control character in a workflow file made it + unparseable, so the Action produced no jobs at all +#> +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' +$Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) +$Fail = 0 +function Assert-Ok { param([string]$Name, [bool]$Ok, [string]$Detail = '') + if ($Ok) { Write-Host (" pass {0}" -f $Name) } + else { $script:Fail++; Write-Host (" FAIL {0} {1}" -f $Name, $Detail) } +} + +Write-Host 'parse' +foreach ($f in (Get-ChildItem $Root -Recurse -Include *.ps1, *.psm1 -File)) { + $errs = $null + [System.Management.Automation.Language.Parser]::ParseFile($f.FullName, [ref]$null, [ref]$errs) | Out-Null + if ($errs) { Assert-Ok $f.Name $false ($errs[0].Message) } +} +if ($Fail -eq 0) { Write-Host ' pass every .ps1 and .psm1 parses' } + +Write-Host 'manifest and import' +$manifest = Join-Path $Root 'TecharyGet.psd1' +try { $m = Test-ModuleManifest $manifest -ErrorAction Stop; Assert-Ok 'Test-ModuleManifest' $true } +catch { Assert-Ok 'Test-ModuleManifest' $false $_.Exception.Message } +try { Import-Module $manifest -Force -ErrorAction Stop; Assert-Ok 'Import-Module' $true } +catch { Assert-Ok 'Import-Module' $false $_.Exception.Message } + +Write-Host 'exports match the files on disk' +$declared = @((Import-PowerShellDataFile $manifest).FunctionsToExport) +$present = @((Get-ChildItem (Join-Path $Root 'Public') -Filter *.ps1 -File).BaseName) +$phantom = @($declared | Where-Object { $_ -notin $present }) +$unexported= @($present | Where-Object { $_ -notin $declared }) +Assert-Ok 'no exported function without a file' ($phantom.Count -eq 0) ($phantom -join ', ') +if ($unexported.Count) { Write-Host (" note present but not exported: {0}" -f ($unexported -join ', ')) } + +Write-Host 'file encoding' +foreach ($f in (Get-ChildItem (Join-Path $Root '.github') -Recurse -Include *.yml, *.yaml -File)) { + $bytes = [IO.File]::ReadAllBytes($f.FullName) + $ctrl = @($bytes | Where-Object { $_ -lt 9 -or ($_ -gt 13 -and $_ -lt 32) }) + $cr = @($bytes | Where-Object { $_ -eq 13 }) + Assert-Ok ("{0}: no control characters" -f $f.Name) ($ctrl.Count -eq 0) ("found {0}" -f $ctrl.Count) + Assert-Ok ("{0}: LF line endings" -f $f.Name) ($cr.Count -eq 0) ("found {0} CR" -f $cr.Count) +} + +Write-Host '' +if ($Fail -gt 0) { Write-Host ("{0} check(s) failed" -f $Fail); exit 1 } +Write-Host 'all structural checks passed' diff --git a/Tests/Test-Normalizer.ps1 b/Tests/Test-Normalizer.ps1 new file mode 100644 index 0000000..4361bea --- /dev/null +++ b/Tests/Test-Normalizer.ps1 @@ -0,0 +1,86 @@ +<# +.SYNOPSIS + Proves the name normaliser matches winget's, using winget's own vectors. + +.DESCRIPTION + Line N of InputNames.txt and InputPublishers.txt must normalise to line N + of NormalizationInitialIds.txt, formatted "." + (NameNormalizationTests.cpp:93-95). + + The C++ test calls Normalize without FoldCase, so the expected values + keep their original case. Our input is folded, so the comparison is + case-insensitive. + + Exits non-zero on any mismatch, so CI fails on a drift. +#> +[CmdletBinding()] +param([int]$ShowFailures = 15) + +$ErrorActionPreference = 'Stop' +$Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) + +Import-Module (Join-Path $Root 'TecharyGet.psd1') -Force +$Module = Get-Module TecharyGet + +$Corpus = Join-Path $Root 'Tests\corpus' +$Names = Get-Content (Join-Path $Corpus 'InputNames.txt') +$Pubs = Get-Content (Join-Path $Corpus 'InputPublishers.txt') +$Want = Get-Content (Join-Path $Corpus 'NormalizationInitialIds.txt') + +if ($Names.Count -ne $Want.Count -or $Pubs.Count -ne $Want.Count) { + throw "Corpus files are not aligned: $($Names.Count) / $($Pubs.Count) / $($Want.Count)" +} + +$Failures = [Collections.Generic.List[object]]::new() + +for ($i = 0; $i -lt $Want.Count; $i++) { + $n = & $Module { Get-WgNormalizedName -Name $args[0] } $Names[$i] + $p = & $Module { Get-WgNormalizedPublisher -Publisher $args[0] } $Pubs[$i] + $got = '{0}.{1}' -f $p, $n.Name + + if (-not [string]::Equals($got, $Want[$i].Trim(), [StringComparison]::OrdinalIgnoreCase)) { + $Failures.Add([pscustomobject]@{ + Line = $i + 1; InName = $Names[$i]; InPublisher = $Pubs[$i] + Expected = $Want[$i].Trim(); Actual = $got + }) + } +} + +$Pass = $Want.Count - $Failures.Count +Write-Host ("normaliser corpus: {0}/{1} pass" -f $Pass, $Want.Count) + +if ($Failures.Count -gt 0) { + Write-Host "" + Write-Host ("first {0} failures:" -f [Math]::Min($ShowFailures, $Failures.Count)) + foreach ($f in ($Failures | Select-Object -First $ShowFailures)) { + Write-Host (" line {0}" -f $f.Line) + Write-Host (" name : '{0}'" -f $f.InName) + Write-Host (" publisher : '{0}'" -f $f.InPublisher) + Write-Host (" expected : {0}" -f $f.Expected) + Write-Host (" actual : {0}" -f $f.Actual) + } + exit 1 +} + +# Anchors from NameNormalizationTests.cpp:110-155 that the corpus does not +# cover, because they assert the architecture field rather than the string. +$ArchCases = @( + @{ In = 'Name'; Arch = 'Unknown' } + @{ In = 'Name x86'; Arch = 'X86' } + @{ In = 'Name x86_64'; Arch = 'X64' } + @{ In = 'Name (64 bit)'; Arch = 'X64' } + @{ In = 'Name 32/64 bit'; Arch = 'Unknown' } + @{ In = 'Fox86'; Arch = 'Unknown' } +) +$ArchFail = 0 +foreach ($c in $ArchCases) { + $r = & $Module { Get-WgNormalizedName -Name $args[0] } $c.In + if ($r.Architecture -ne $c.Arch) { + $ArchFail++ + Write-Host ("architecture: '{0}' expected {1}, got {2}" -f $c.In, $c.Arch, $r.Architecture) + } +} +Write-Host ("architecture anchors: {0}/{1} pass" -f ($ArchCases.Count - $ArchFail), $ArchCases.Count) +if ($ArchFail -gt 0) { exit 1 } + +Write-Host "all normaliser checks passed" diff --git a/Tests/corpus/InputNames.txt b/Tests/corpus/InputNames.txt new file mode 100644 index 0000000..3d33d50 --- /dev/null +++ b/Tests/corpus/InputNames.txt @@ -0,0 +1,1137 @@ +0 A.D. +010 Editor 11.0 (64-bit) +360安全卫士 +360杀毒 +4K Slideshow Maker 1.8 +4K Stogram +4K Video Downloader +4K Video Downloader 4.12 +4K Video to MP3 +4K YouTube to MP3 3.12 +7-Zip 16.04 (x64 edition) +7-Zip 19.00 (x64 edition) +7-Zip 20.02 alpha (x64) +7-Zip ZS 19.00 ZS v1.4.5 R2 (x64) +AWS Command Line Interface +AWS Command Line Interface v2 +AWS SAM Command Line Interface +AXIS Camera Station 5.33 +AbaClient +Accessibility Insights For Windows v1.1 +Active Directory Authentication Library for SQL Server +Adobe Acrobat Reader DC - Czech +Adobe Acrobat Reader DC +Adobe Acrobat Reader DC MUI +AdoptOpenJDK JDK with Hotspot 11.0.7.10 (x64) +AdoptOpenJDK JDK with Hotspot 11.0.8.10 (x64) +AdoptOpenJDK JDK with Hotspot 14.0.1.7 (x64) +AdoptOpenJDK JDK with Hotspot 14.0.2.12 (x64) +AdoptOpenJDK JDK with Hotspot 15.0.0.36 (x64) +AdoptOpenJDK JDK with Hotspot 8.0.252.09 (x64) +AdoptOpenJDK JDK with Hotspot 8.0.265.01 (x64) +Advanced IP Scanner 2.5 +Advanced Log Viewer 8.1.0 +Advanced Port Scanner 2.5 +AdvancedRestClient 15.0.5 +Aegisub 8975-master-8d77da3 +Aegisub r8942 +AeroZoom 4.0 beta 2 +Alacritty +Alchemy Beta x64 +Algodoo v2.1.0 +AltDrag +Amazon Chime +Amazon Corretto (x64) +Amazon Corretto 8 (x64) +Amazon WorkSpaces +Anaconda3 2020.07 (Python 3.8.3 64-bit) +Angry IP Scanner +AntiMicro +AppGet +Appium 1.15.1 +Appium 1.18.3 +Arduino +Armagetron Advanced 0.2.8.3.5 +Artha 1.0.3.0 +AssaultCube 1.2.0.2 +Audacity 2.4.2 +AuthPass version 1.7.9_1605 +Auto Dark Mode +AutoHotkey 1.1.32.00 +AutoHotkey 1.1.33.02 +Autopsy +AviSynth 2.6 +Avro Keyboard 5.6.0 +Aya +Azure Cosmos DB Emulator +Azure Data Studio (User) +Azure Functions Core Tools - 3.0.2534 (x64) +Azure IoT Explorer (preview) +Azure IoT explorer +BCUninstaller +BITS Manager +BKChem-0.13.0 +BOINC +BPBible 0.5.3.1 +Backup and Sync from Google +Barrier 2.3.2-snapshot +Barrier 2.3.3-release +Beaker Browser 0.8.10 +Beats winlogbeat 7.7.0 (x86_64) +Beats winlogbeat 7.9.2 (x86_64) +BeeBEEP 5.8.2 +Beeftext +Betaflight Configurator +Beyond Compare 4 +Beyond Compare 4.3.6 +Beyond Compare 4.3.7 +BiglyBT +BitPay version 4.8.1 +Bitwarden +BleachBit 4.0.0.1628 (current user) +Blender +BlueJeans +Bob the Hamster VGA 2008-01-23 +Bonjour +Borderless Gaming +Bot Framework Composer 1.0.0 +Bot Framework Composer 1.0.1 +Bot Framework Composer 1.0.2 +Bot Framework Composer 1.1.1 +Bot Framework Emulator 4.10.0 +Bot Framework Emulator 4.8.1 +Bot Framework Emulator 4.9.0 +Brackets +Brave +Brave Nightly +Bulk Rename Utility 3.3.1.0 (64-bit) +Buttercup 1.19.0 +Buttercup 1.20.0 +C-Dogs SDL +CCEnhancer version 4.5.6 +CCleaner +CDBurnerXP (64 bit) +CMake +CORSAIR iCUE Software +CPUID CPU-Z 1.92 +CPUID CPU-Z 1.93 +CPUID CPU-Z 1.94 +CPUID HWMonitor 1.41 +CPUID HWMonitor 1.42 +Cacher +CaesiumPH 0.9.5 +Camtasia 2019 +Camtasia 2020 +Caprine 2.47.0 +Caprine 2.48.0 +Caption 2.0.1 (only current user) +Captura v8.0.0 +CemUI 2.3.3 (only current user) +Cerebro 0.3.2 +CertAid for Windows +CertDump +Certify The Web version 5.1.5 +ChMac 2.0 +ChefDK v4.11.0 +ChemAxon ChemCurator +ChemAxon Markush Editor +ChemAxon Marvin Suite 20.13.0 +ChemAxon Marvin Suite 20.19.0 +Chromium +Circuit Diagram version 3.0 +Circuit Diagram version 3.1 +Cisco Webex Meetings +Citycraft Launcher 1.9.9 +ClamWin Free Antivirus 0.99.4 +Clash for Windows 0.11.1 +Clash for Windows 0.11.6 +Clash for Windows 0.11.8 +Clash for Windows 0.9.11 +ClassIn +Clementine +Clink v0.4.9 +Cloudflare WARP +CodeBlocks +CodeLite +Coffee +Colobot: Gold Edition alpha-0.1.12 +Color Cop 5.4.3 +Colorpicker 2.0.3 +ConEmu 201011.x64 +Concept2 Utility +ConfigMgr 2012 Toolkit R2 +Contasimple Desktop 3.1.0 +Core Temp 1.16 +Couchbase Server 6.5.1-6299 Community Edition +Couchbase Server 6.5.1-6299 Enterprise Edition +Cozy Drive 3.20.0 +Cppcheck x64 2.0 +Crypter 4.0.0 +Cryptomator +CrystalDiskInfo 8.6.1 +CrystalDiskInfo 8.6.2 +CrystalDiskInfo 8.6.2 Kurei Kei Edition +CrystalDiskInfo 8.6.2 Shizuku Edition +CrystalDiskInfo 8.7.0 +CrystalDiskInfo 8.8.1 +CrystalDiskInfo 8.8.1 Kurei Kei Edition +CrystalDiskInfo 8.8.1 Shizuku Edition +CrystalDiskInfo 8.8.5 +CrystalDiskInfo 8.8.9 +CrystalDiskInfo 8.8.9 Kurei Kei Edition +CrystalDiskInfo 8.8.9 Shizuku Edition +CrystalDiskInfo 8_8_2 +CrystalDiskInfo 8_8_2 Kurei Kei Edition +CrystalDiskInfo 8_8_2 Shizuku Edition +CrystalDiskMark 7.0.0h +CrystalDiskMark 7.0.0h Shizuku Edition +CubicSDR 0.2.5 Installer +CutePDF Writer +Cyberduck +DB Browser for SQLite +DBeaver 7.0.5 (current user) +DBeaver 7.1.0 (current user) +DBeaver 7.1.2 (current user) +DBeaver 7.1.3 (current user) +DBeaver 7.1.4 (current user) +DBeaver 7.2.0 (current user) +DBeaver 7.2.1 (current user) +DBeaver 7.2.2 (current user) +DBeaver 7.2.3 (current user) +DJI Assistant 2 (DJI FPV series) version V2.0.2.11 +DJI Assistant 2 For Aeroscope version V2.0.1.3 +DJI Assistant 2 For Autopilot version V2.0.3.7 +DJI Assistant 2 For Battery Station version V2.0.1.9 +DJI Assistant 2 For MG version V2.0.18.1 +DJI Assistant 2 For Matrice version V2.0.13.2 +DJI Assistant 2 For Mavic version V2.0.14.1 +DJI Assistant 2 For Phantom version V2.0.10.4 +Dave Gnukem +DeepVocalToolBox_beta_1.1.6 version beta_1.1.6 +DeepVocal_beta_1.1.6 version beta_1.1.6 +Deezer 4.19.20 +DefaultAudio +Defraggler +Dell Command | Update +Dell Update +Dev-C++ +Dimension 4 v5.31 +Discord Media Loader version 1.3.0.0 +Discord Media Loader version 1.4.0.0 +Ditto +Dixa +DjVuLibre DjView 3.5.27+4.11 +DockStation 1.5.1 +Docker Desktop +Dokan Library 1.3.0.1000 (x64) +Dokan Library 1.4.0.1000 (x64) +Dolphin +Doomsday 2.2.2.3313 +Dopamine +Doxie 2.12.2 +Dropbox +EGR-SafenetActivation +EGR-ShellExtension +EagleGet version 2.1.5.10 +EagleGet version 2.1.6.70 +EasyConnect +EditPlus (64 bit) +EduMIPS64 +Elasticsearch 7.9.2 +Elgato Stream Deck +Empoche 0.4.0 +Empoche 0.4.3 +Encrypto version 1.0.1 +EnglishizeCmd 2.0 +Enpass +Eraser 6.2.0.2986 +Eraser 6.2.0.2988 +Eraser 6.2.0.2989 +Eraser 6.2.0.2990 +Esteem 2.2.7 +Ethereum - Geth - Official Go implementation of the Ethereum protocol +Evernote v. 6.21.2 +Evernote v. 6.24.2 +Everything 1.4.1.969 (x64) +Everything 1.4.1.986 (x64) +Everything 1.4.1.988 (x64) +Everything 1.4.1.988 Lite (x64) +Everything 1.4.1.992 (x64) +ExpressVPN +Expresso +Extreme TuxRacer 0.8 (x64) +Far Manager 3 x64 +FastCopy +FastStone Capture 9.3 +FastStone Image Viewer 7.5 +Fedora Media Writer +Ferdi 5.5.0 +Fiddler Everywhere 1.0.2 +Fiddler Everywhere 1.1.0 +Fiddler Everywhere 1.1.0-insiders +Fiddler Everywhere 1.1.0-internal +Fiddler Everywhere 1.1.1 +Fiddler Everywhere 1.1.1-insiders +Fiddler Everywhere 1.1.1-internal +File Converter (64 bit) +FileSeek 6.4 +FileZilla Client 3.47.0 +FileZilla Client 3.48.1 +FileZilla Client 3.49.1 +FileZilla Client 3.50.0 +FileZilla Client 3.51.0 +Firefox Developer Edition 77.0 (x64 en-US) +Firefox Developer Edition 78.0 (x64 en-US) +Firefox Developer Edition 80.0 (x64 en-US) +Firefox Developer Edition 82.0 (x64 en-US) +FlashFXP 5 +FlightGear v2018.3.5 +FontBase 2.11.3 +FontForge version 14-03-2020 +FormatFactory 5.3.0.1 +FormatFactory 5.4.5.0 +Foxit PhantomPDF +Foxit Reader +Franz 5.5.0 +FreeCommander XE +FreeMat +GIMP 2.10.0 +GIMP 2.10.10 +GIMP 2.10.14 +GIMP 2.10.16 +GIMP 2.10.18 +GIMP 2.10.20 +GIMP 2.10.6 +GIMP 2.10.8 +GNU Arm Embedded Toolchain 9-2020-q2-update 9 2020 (remove only) +GNU Midnight Commander version 4.8.24 (build: 20200521-217) +GNU Privacy Guard +GNURadio-3.7 +GOG GALAXY +GPL Ghostscript +GSview 5.0 +Garmin Express +Gauge 1.0.6 +Gauge 1.1.1 +Geany 1.36 +Geekbench 5 +Gephi 0.9.2 +GetDiz +Git Extensions 3.3.1.7897 +Git Extensions 3.4.1.9675 +Git Extensions 3.4.3.9999 +Git LFS version 2.11.0 +Git version 2.24.1.2 +Git version 2.25.1 +Git version 2.26.2 +Git version 2.27.0 +Git version 2.28.0 +Git version 2.29.0 +GitHub CLI +GitHub Desktop Machine-Wide Installer +GitHubReleaseNotes +Gitter +Glimpse 0.1.2 +Glimpse 0.2.0 (64-bit) +Glimpse 0.2.0 +GnuCash 3.9 +GnuCash 4.1 +GnuWin32: Grep-2.5.4 +GnuWin32: Make-3.81 +GnuWin32: Wget-1.11.4-1 +GnuWin32: Zip-3.0 +Go Programming Language amd64 go1.13.12 +Go Programming Language amd64 go1.13.13 +Go Programming Language amd64 go1.13.14 +Go Programming Language amd64 go1.13.15 +Go Programming Language amd64 go1.14.10 +Go Programming Language amd64 go1.14.3 +Go Programming Language amd64 go1.14.4 +Go Programming Language amd64 go1.14.5 +Go Programming Language amd64 go1.14.6 +Go Programming Language amd64 go1.14.7 +Go Programming Language amd64 go1.14.8 +Go Programming Language amd64 go1.14.9 +Go Programming Language amd64 go1.15 +Go Programming Language amd64 go1.15.1 +Go Programming Language amd64 go1.15.2 +Go Programming Language amd64 go1.15.3 +Go Programming Language amd64 go1.15beta1 +GoldWave v6.52 +Google Chrome +Google Cloud SDK +Google Earth Pro +Gpg4win (3.1.11) +Gpg4win (3.1.13) +GrafanaEnterprise +GrafanaOSS +Grammarly for Microsoft® Office Suite +GrampsAIO64 +GraphQL Playground 1.8.10 +GraphiQL 0.7.2 +Graphviz +Greenshot 1.2.10.6 +Grid 1.6.2 +Grindstone 4 +HHD Software Free Hex Editor Neo 6.44 +HM NIS Edit 2.0.3 +HP Cloud Recovery Tool +HUAWEI Cloud +HWiNFO64 Version 6.26 +HWiNFO64 Version 6.28 +HWiNFO64 Version 6.30 +HWiNFO64 Version 6.32 +HandyWinGet +Harmony 0.9.1 (only current user) +HashTab 5.2.0.14 +HashTab 6.0.0.34 +HeavyLoad V3.6 (64 bit) +Hedgewars +HeidiSQL 11.0.0.5919 +HeidiSQL 11.0.0.5995 +HeidiSQL 11.0.0.5997 +HeidiSQL 11.0.0.6000 +HeidiSQL 11.0.0.6057 +Helix Core Apps +HelpNDoc 6.9.0.577 Personal Edition +HexChat +Hosts File Editor +Hover +HttpMaster Express Edition 4.7.0 +HttpMaster Express Edition 4.7.1 +HttpMaster Express Edition 4.7.2 +HttpMaster Express Edition 4.7.3 +HttpMaster Professional Edition 4.7.1 +HttpMaster Professional Edition 4.7.2 +HttpMaster Professional Edition 4.7.3 +Huawei QuickApp IDE +Hyne Timber Design 7.5.14.0 +Hyperspace Desktop 1.1.3 +IAP Desktop +IDA Freeware 7.0 +IO Ninja 3 +IPFilter 3.0.2.9-beta +IRCCloud 0.15.0 +IZArc 4.4 +ImageGlass +Inkscape +Inno Setup version 6.0.4 +Inno Setup version 6.0.5 +InternetOff 3.0, 32\64 bit edition +Intuiter 0.5.0 +IrfanView 4.54 (64-bit) +IronPython 2.7.10 +IronPython 2.7.9 +IsWiX +IsoBuster 4.6 +JChem .NET API 20.19.0.482 +JabRef +Jackett +Jami +Java 8 Update 251 (64-bit) +Java 8 Update 261 (64-bit) +JetBrains Toolbox +Jitsi Meet 2.3.1 +Jitsi Meet 2.4.1 +Joplin 1.0.201 +Joplin 1.0.216 +Joplin 1.0.233 +Julia 1.4.1 +Julia 1.4.2 +Julia 1.5.1 +K-Lite Codec Pack 15.7.0 Standard +K-Lite Mega Codec Pack 15.7.0 +KKBOX +Kaku 2.0.2 +KeePass Password Safe 2.44 +KeePass Password Safe 2.45 +KeePass Password Safe 2.46 +KeePassXC +KeeWeb +Keybase +KiCad 5.1.5_1 +KiCad 5.1.6_1 +KiCad 5.1.7_1 +Krisp +Krita (x64) 4.3.0 +L'Math version r1.6 +LBRY 0.45.1 +LBRY 0.45.2 +LBRY 0.46.2 +LBRY 0.47.0 +LBRY 0.47.1 +LINE +LINQPad 6 +LLVM +LMMS 1.2.1 +LMMS 1.2.2 +LOVE 11.3 +Laragon 4.0.15 +LastPass (uninstall only) +Lazarus 2.0.8 +League of Legends +Lenovo Migration Assistant +Lenovo System Update +Lens 3.5.1 +Leonflix 0.7.0 +Liberica JDK 11 (64-bit) +Liberica JDK 11 Full (64-bit) +Liberica JDK 14 (64-bit) +Liberica JDK 14 Full (64-bit) +Liberica JDK 15 (64-bit) +Liberica JDK 15 Full (64-bit) +Liberica JDK 8 (64-bit) +Liberica JDK 8 Full (64-bit) +LibreCAD +LibreOffice 7.0.1.2 +LibreOffice 7.0.2.2 +Lidarr version 0.7.1 +LightBulb 2.0 +LightBulb 2.2 +Lightscreen version 2.4 +Linrad-04.14a version 04.14a +Lisk Hub 1.22.0 +Listen1 2.13.0 +Listen1 2.5.2 +Local 5.5.3 +LockHunter 3.3, 32/64 bit +LogFusion 6.4 +LogFusion 6.4.1 +Logitech Gaming Software 9.02 +Loom 0.37.2 +LyX 2.3.4.4 +LyX 2.3.5.2 +MCX Studio version nightlybuild +MCX Studio version v2020 +MKVToolNix 46.0.0 (64-bit) +MKVToolNix 47.0.0 (64-bit) +MKVToolNix 48.0.0 (64-bit) +MKVToolNix 49.0.0 (64-bit) +MKVToolNix 50.0.0 (64-bit) +MPC-HC 1.7.13 (64-bit) +MPC-HC 1.9.5 (64-bit) +MPC-HC 1.9.6 (64-bit) +MQTT Explorer 0.3.5 +MSIX Core +MX5 +MY.GAMES GameCenter +MacType +MailWasher +MailWasherPro +Majsoul Plus 2.0.0 +MakeMKV v1.15.3 +Malwarebytes version 4.2.1.89 +Marble version 2.2.0 +MariaDB 10.5 (x64) +Mark Text 0.16.2 +Markdown Monster 1.22.8.0 +Markdown Monster 1.23.0.0 +Markdown Monster 1.23.12.0 +Markdown Monster 1.23.14.0 +Markdown Monster 1.24.12.0 +Markdown Outlook +Master Packager +Mattermost +MediaInfo 20.09 +MediaInfo-CLI 20.09 +MediaMonkey 4.1 +Meld +Memurai Developer +Microsoft .NET Core SDK 3.1.202 (x64) +Microsoft .NET Core SDK 3.1.300 (x64) +Microsoft .NET Core SDK 3.1.301 (x64) +Microsoft .NET Core SDK 3.1.302 (x64) +Microsoft .NET Core SDK 3.1.401 (x64) +Microsoft .NET Core SDK 3.1.402 (x64) +Microsoft .NET Framework 4.5 Multi-Targeting Pack +Microsoft .NET Framework 4.5.1 Multi-Targeting Pack (ENU) +Microsoft .NET Framework 4.5.1 Multi-Targeting Pack +Microsoft .NET Framework 4.5.1 SDK +Microsoft .NET Framework 4.5.2 Multi-Targeting Pack (ENU) +Microsoft .NET Framework 4.5.2 Multi-Targeting Pack +Microsoft .NET Framework 4.7.2 SDK +Microsoft .NET Framework 4.7.2 Targeting Pack +Microsoft .NET Framework 4.8 SDK +Microsoft .NET Framework 4.8 Targeting Pack +Microsoft .NET SDK 5.0.100-preview.5.20279.10 (x64) +Microsoft .NET SDK 5.0.100-preview.8.20417.9 (x64) +Microsoft .NET SDK 5.0.100-rc.1.20452.10 (x64) +Microsoft .NET SDK 5.0.100-rc.2.20479.15 (x64) +Microsoft Azure CLI +Microsoft Azure Storage Emulator - v5.10 +Microsoft Azure Storage Explorer version 1.14.0 +Microsoft Azure Storage Explorer version 1.15.1 +Microsoft Deployment Toolkit (6.3.8456.1000) +Microsoft Edge +Microsoft Edge Beta +Microsoft Edge Dev +Microsoft Garage Mouse without Borders +Microsoft Help Viewer 2.2 +Microsoft Help Viewer 2.3 +Microsoft MPI (10.1.12498.16) +Microsoft MPI (10.1.12498.18) +Microsoft MPI SDK (10.1.12498.18) +Microsoft ODBC Driver 13 for SQL Server +Microsoft ODBC Driver 17 for SQL Server +Microsoft OLE DB Driver for SQL Server +Microsoft R Open 3.5.3 +Microsoft R Open 4.0.2 +Microsoft SQL Server 2012 Native Client +Microsoft SQL Server 2014 Management Objects +Microsoft SQL Server 2016 +Microsoft SQL Server 2016 Policies +Microsoft SQL Server 2016 T-SQL Language Service +Microsoft SQL Server 2016 T-SQL ScriptDom +Microsoft SQL Server 2017 +Microsoft SQL Server 2017 Policies +Microsoft SQL Server 2017 T-SQL Language Service +Microsoft SQL Server Data-Tier Application Framework (x86) +Microsoft SQL Server Management Studio - 16.5.3 +Microsoft SQL Server Management Studio - 17.9.1 +Microsoft SQL Server Management Studio - 18.5 +Microsoft SQL Server Management Studio - 18.5.1 +Microsoft SQL Server Management Studio - 18.6 +Microsoft Small Basic v1.2 +Microsoft System CLR Types for SQL Server 2014 +Microsoft System CLR Types for SQL Server 2016 +Microsoft System CLR Types for SQL Server 2017 +Microsoft Visio Viewer 2016 +Microsoft Visual Studio 2010 Tools for Office Runtime (x64) +Microsoft Visual Studio 2015 Shell (Isolated) +Microsoft Visual Studio Code (User) +Microsoft Visual Studio Code Insiders (User) +Microsoft Visual Studio Tools for Applications 2015 +Microsoft Visual Studio Tools for Applications 2015 Language Support +Microsoft Visual Studio Tools for Applications 2017 +Microsoft Web Platform Installer 5.1 +Miniconda3 4.7.12 (Python 3.7.4 64-bit) +Miniconda3 py37_4.8.3 (Python 3.7.7 64-bit) +MongoDB 4.2.8 2008R2Plus SSL (64 bit) +Mono for Windows (x64) +MonoGame SDK +Moonlight Game Streaming Client +Motrix 1.5.10 +Motrix 1.5.15 +Mozilla Firefox 68.8.0 ESR (x64 en-US) +Mozilla Firefox 68.9.0 ESR (x64 en-US) +Mozilla Firefox 76.0.1 (x86 en-US) +Mozilla Firefox 77.0 (x64 en-US) +Mozilla Firefox 77.0.1 (x64 en-US) +Mozilla Firefox 78.0 ESR (x64 en-US) +Mozilla Firefox 78.0.1 (x64 en-US) +Mozilla Firefox 78.0.2 (x64 cs) +Mozilla Firefox 78.0.2 (x64 en-US) +Mozilla Firefox 78.1.0 ESR (x64 en-US) +Mozilla Firefox 78.4.0 ESR (x64 en-US) +Mozilla Firefox 79.0 (x64 en-US) +Mozilla Firefox 80.0 (x64 en-US) +Mozilla Firefox 80.0.1 (x64 en-US) +Mozilla Firefox 81.0 (x64 en-US) +Mozilla Firefox 81.0.1 (x64 en-US) +Mozilla Firefox 81.0.2 (x64 en-US) +Mozilla Firefox 82.0 (x64 en-US) +Mozilla Firefox 82.0.1 (x64 en-US) +Mozilla Firefox 82.0.1 (x64 es-MX) +Mozilla Firefox 82.0.2 (x64 en-US) +Mozilla Maintenance Service +Mozilla Thunderbird 68.10.0 (x64 en-US) +Mozilla Thunderbird 68.8.0 (x86 en-US) +Mozilla Thunderbird 68.9.0 (x64 en-US) +Mozilla Thunderbird 77.0 (x64 en-US) +Mozilla Thunderbird 78.0 (x64 cs) +Mozilla Thunderbird 78.0 (x64 en-US) +Mozilla Thunderbird 78.0.1 (x64 en-US) +Mozilla Thunderbird 78.1.0 (x64 en-US) +Mozilla Thunderbird 78.1.1 (x64 en-US) +Mozilla Thunderbird 78.3.2 (x64 en-US) +Mu +Mullvad VPN 2020.5.0 +Mullvad VPN 2020.6.0 +Multilingual App Toolkit 4.0 +Multipass +Mumble 1.3.1 +Mumble 1.3.2 +Mumble 1.3.3 +MuseScore 3 +Muta 2.1.02 +MyHarmony +MyPaint +MySQL Installer - Community +Mypal 28.14.2 (x64 en-US) +NBTExplorer +NSwagStudio +NVDA +NVIDIA NVIDIA RTX Voice Driver 1.0.0.2 +NVIDIA RTX Voice Application +NZXT CAM 4.10.1 +NZXT CAM 4.11.0 +NZXT CAM 4.12.0 +NZXT CAM 4.13.0 +NZXT CAM 4.8.0 +NZXT CAM 4.9.2 +Nelson-0.4.8.2662 (64 bits) +NeoLoad 7.3.0 +Netron 4.5.9 +Nitro Pro +Nmap 7.80 +NoSQLBooster for MongoDB 4.7.5 (only current user) +NoSQLBooster for MongoDB 5.2.12 +NoSQLBooster for MongoDB 6.1.8 +Node.js +Nodist +NordVPN +NordVPN +NordVPN network TAP +NordVPN network TUN +NoteHighlight2016 +Notepad2-mod 4.2.25.998 +Notion 2.0.8 +Notion 2.0.9 +Npcap 0.9982 +NullpoMino version 7.5 +Nullsoft Install System +OBS Studio +OHRRPGCE gorgonzola 20200502 +ONLYOFFICE Desktop Editors 5.6 (x64) +Octave 5.2.0 +OneNote Tagging Kit +Open Shop Channel Downloader version 1.2.9 +Open-Shell +OpenHashTab version 2.2.0 +OpenHashTab version 2.3.0 +OpenJDK 1.8.0_252-2-ojdkbuild +OpenJDK 11.0.7-1-ojdkbuild +OpenJDK 13.0.3-1-ojdkbuild +OpenJDK 14.0.1-1-ojdkbuild +OpenMPT 1.29 (64-Bit) +OpenOffice 4.1.7 +OpenRA +OpenSCAD (remove only) +OpenSSL (64-bit) +OpenShot Video Editor version 2.5.1 +OpenTTD 1.10.1 +OpenTTD 1.10.3 +OpenVPN 2.4.9-I601-Win10 +OpenVPN Configuration Generator x64 +OpenVPN Connect +Opera GX Stable 68.0.3618.142 +Opera GX Stable 68.0.3618.197 +Opera Stable 68.0.3618.63 +Opera Stable 69.0.3686.36 +Opera Stable 69.0.3686.77 +Opera Stable 70.0.3728.144 +Opera Stable 70.0.3728.95 +Opera Stable 71.0.3770.198 +Oracle VM VirtualBox 6.1.10 +Oracle VM VirtualBox 6.1.12 +Oracle VM VirtualBox 6.1.14 +Oracle VM VirtualBox 6.1.16 +OutSystems Development Environment 11 +PDF reDirect (remove only) +PDFsam Basic +PKU_Gateway 0.9.8 +PSPad editor +Packet Sender x64 +Pale Moon 28.10.0 (x64 en-US) +Pale Moon 28.9.3 (x64 en-US) +Pandoc 2.10.1 +Pandoc 2.11.0.2 +Pandoc 2.9.2.1 +Paradox Launcher +Paragon Backup & Recoveryâ„¢ 17 CE +Parsec +PasteIntoFile version 2.0 +PeaZip 7.2.1 (WIN64) +PeaZip 7.3.1 (WIN64) +Persepolis Download Manager version 3.2.0.0 +PhonerLite 2.84 +PhotoSync +PicPick +PicoTorrent +Planet Blupi +PlayStationâ„¢Now +Playnite +Plex +Plex Media Player +Plex Media Server +Plexamp 3.0.3 +Plexamp 3.1.0 +Plexamp 3.1.1 +PokerTH +Postbox 7.0.18 (x86 en-US) +PostgreSQL 12 +PostgreSQL 13 +PowerShell 7-preview-x64 +PowerShell 7-x64 +PowerShell Universal +PowerToys (Preview) +Primesieve version 7.5 +Private Internet Access +Progress Telerik Fiddler +Project My Screen App +ProtonVPN +ProtonVPNTap +PuTTY release 0.74 (64-bit) +Puppet +Puppet Agent (64-bit) +Puppet Bolt +Puppet Development Kit +Pure Data (64-bit) 0.50-2 +PyMODA version 1.1.0 +Python 2.7.18 +Python 3.7 PyAudio-0.2.11 +Python 3.7.7 (64-bit) +Python 3.8.1 (64-bit) +Python 3.8.3 (64-bit) +Python 3.8.4 (64-bit) +Python 3.8.5 (64-bit) +Python 3.8.6 (64-bit) +Python 3.9.0 (64-bit) +Python Launcher +QGIS 3.10.6 'A Coru +QGIS 3.12.3 'Bucuresti' +QGIS 3.14.0 'Pi' +QTextPad version 1.4 +Qalculate! +QtSpim +Quick Picture Viewer +QuickLook +Quicken +R for Windows 4.0.0 +R for Windows 4.0.2 +R for Windows 4.0.3 +RStudio +Rambox 0.7.5 +Rapid Environment Editor version 9.2.0.937 +Raspberry Pi Imager +RawTherapee version 5.8 +Reddit Wallpaper Changer +Reko decompiler for x86-64 +Remote Desktop Manager +Remote Desktop Manager Free +Remote Mouse version 3.015 +RenderDoc +Renode +ResponsivelyApp 0.1.5 +RetroShare +Revo Uninstaller 2.1.7 +Revo Uninstaller Pro 4.3.3 +Robo 3T 1.3.1 +Robo 3T 1.4.1 +Robo 3T 1.4.2 +Rocket.Chat 2.17.9 +RocketDock 1.3.5 +Rocks'n'Diamonds 4.1.4.1 +Rosi +Royal TS 5.02.60420.0 +Royal TS 5.03.60925.0 +Rtools 4.0 (4.0.0.28) +Ruby 2.7.1-1-x64 +Ruby 2.7.1-1-x64 with MSYS2 +Ruby 2.7.2-1-x64 +RunJS 1.10.1 +RunJS 1.11.0 +Rust 1.43 (MSVC 64-bit) +Rust 1.44 (GNU 64-bit) +Rust 1.44 (GNU) +Rust 1.44 (MSVC 64-bit) +Rust 1.44 (MSVC) +Rust 1.45 (GNU 64-bit) +Rust 1.45 (GNU) +Rust 1.45 (MSVC 64-bit) +Rust 1.45 (MSVC) +SIW 2020 v10.6.0915a Trial +SMPlayer 20.4.2 (x64) +SSHFS-Win 2020 (x64) +SVG Explorer Extension 0.1.1 +Samsung DeX +Satisfactory Mod Launcher 1.0.17 +Scratch Desktop 3.11.1 +ScreenToGif +Scribus 1.4.8 (64bit) +ScummVM 2.2.0 +Search Deflector +Sejda PDF Desktop +Seq +SharePoint Online Management Shell +ShareX +SharpKeys +Shotcut +Sigil 1.3.0 +Signal 1.34.1 +Signal 1.34.3 +Signal 1.34.4 +Signal 1.34.5 +Signal 1.36.1 +Signal 1.36.3 +Signal 1.37.2 +Simply Fortran 3 +SitdownMW +Skype version 8.60 +Skype version 8.64 +Skype version 8.65 +Slack Machine-Wide +Snagit 2020 +SnakeTail 64-bit v1.9.6.0 +Snoop +SoapUI 5.5.0 +Sonic Pi +Sonos +Sonos Controller +SoundSwitch 5.0.4.31153 +Sourcetree +SpeedCrunch +Spek +Standard Notes 3.4.1 +Steam +Steel Bank Common Lisp 2.0.0 (X86-64) +SteelSeries Engine 3.17.9 +Stellarium 0.20.1 +Stellarium 0.20.2 +Stellarium 0.20.3 +Strawberry Perl +Streamlabs OBS +Streamlabs OBS 0.23.2 +Streamlabs OBS 0.24.0 +Streamlink +Streamlink Twitch GUI +Stretchly 1.0.0 +Stretchly 1.1.0 +Stretchly 1.2.0 +Stride +Studio 2.0 version 2.0 +Sublime Merge +Sublime Text 3 +SumatraPDF +SuperCollider Version 3.11.0 +SuperTuxKart 1.1.0 - 3D open-source arcade racer with a variety characters, tracks, and modes to play +Surface Duo Emulator version 2020.806.2 +SyncTrayzor (x64) version 1.1.24.0 +System Explorer 7.0.0 +TAP-Windows 9.24.2 +Taiga +Tailscale +Tailscale IPN +Taisei Project +Taskade 3.1.1 +Taskade 3.2.0 +Td-agent v3.8.0 +Td-agent v4.0.1 +TeXstudio - TeXstudio is a fully featured LaTeX editor. +TeXworks 0.6.5 +TeamSpeak 3 Client +TechPowerUp GPU-Z +Telegram Desktop version 2.1.13 +Telegram Desktop version 2.1.20 +Telegram Desktop version 2.1.6 +Telegram Desktop version 2.2 +Telegram Desktop version 2.3 +Telegram Desktop version 2.3.1 +Telegram Desktop version 2.4.1 +Telegram Desktop version 2.4.3 +Telegram Desktop version 2.4.4 +Tera Term 4.105 +Terminus 1.0.117 +Terminus 1.0.119 +Terminus 1.0.120 +Termite +Tesseract-OCR - open source OCR engine +Texmaker 5.0.4 (64-bit) +Texnomic SecureDNS Terminal +Textify v1.8.2 +TickTick version 3.7.1.1 +TightVNC +TikzEdt 0.2.3 +Tiled +TmNationsForever +Toggl Desktop +Toggl Track +TortoiseGit 2.10.0.2 (64 bit) +TortoiseSVN 1.13.1.28686 (64 bit) +TortoiseSVN 1.14.0.28885 (64 bit) +TranslucentTB +Transmission 3.00 (bb6b5a062e) (x64) +Transmission Remote GUI 5.18 +TrayStatus 4.3 +TrayStatus 4.4 +TreeSize Free V4.4.2 +TreeSize V8.0.2 (64 bit) +Trelby +Trillian +TunnelBear +Tux Paint 0.9.23 +Tweeten +Twinkle Tray 1.12.2 +Twitch +TypeRefHasher +USB Safely Remove 6.3 +UXL Launcher Version 3.3.1.0 +UXL Launcher Version 4.0.0.0 +Ultimaker Cura +Ultimaker Cura 4.5 +Ultimaker Cura 4.6 +UltraVnc +Unchecky v1.2 +Unified Remote +Unity Hub 2.4.2 +Update for (KB2504637) +Update for Microsoft Visual Studio 2015 (KB3095681) +Uplay +Ut Video Codec Suite +VCV Rack +VLC media player 3.0.10 (64-bit) +VLC media player 3.0.11 (64-bit) +VLC media player 4.0.0 (64-bit) +VMware Horizon Client +VMware Player +VMware Workstation +VNC Server 6.0.0 +VNC Viewer 6.0.0 +VSCodium (User) +VSCodium +VcXsrv +Vim 8.2 (x64) +VirtViewer 9.0-256 (64-bit) +Vivaldi +Vortex +Vrew 0.4.18 +VulkanSDK 1.2.135.0 +Warzone 2100-3.4.0 +Waterfox Current 2020.05 (x64 en-US) +Waterfox Current 2020.09 (x64 en-US) +Waterfox Current 2020.10 (x64 en-US) +Wayk Now +WeakAuras Companion 3.0.1 +WeakAuras Companion 3.0.2 +WeakAuras Companion 3.0.3 +WeakAuras Companion 3.0.6 +Weka 3.8.4 +Win32DiskImager version 1.0.0 +WinCompose version 0.9.4 +WinDynamicDesktop version 3.4.1.0 +WinDynamicDesktop version 4.2.0.0 +WinDynamicDesktop version 4.3.1.0 +WinFsp 2020 +WinHTTrack Website Copier 3.49-2 (x64) +WinMerge 2.16.6.0 +WinRAR 5.90 (64-bit) +WinRAR 5.91 (64-bit) +WinSCP 5.17.7 +WinZip 24.0 +Winamp +Windows 10 Update Assistant +Windows Admin Center +Windows Assessment and Deployment Kit - Windows 10 +Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons - Windows 10 +Windows Driver Kit - Windows 10.0.19041.1 +Windows Driver Package - Dynastream Innovations, Inc. ANT LibUSB Drivers (04/11/2012 1.2.40.201) +Windows Driver Package - Silicon Labs Software (DSI_SiUSBXp_3_1) USB (02/06/2007 3.1) +Windows SDK AddOn +Windows Software Development Kit - Windows 10.0.17763.132 +Windows Software Development Kit - Windows 10.0.18362.1 +Windows Software Development Kit - Windows 10.0.19041.1 +WireGuard +Wireshark 3.2.2 32-bit +Wireshark 3.2.4 64-bit +Wireshark 3.2.5 64-bit +Wireshark 3.2.7 64-bit +WizFile v2.06 +WizKey v1.5.0.8 +WizMouse v1.7.0.3 +WizTree v3.33 +WizTree v3.35 +WordPress.com 5.2.0 +WordPress.com 6.0.0 +WordPress.com 6.0.1 +WordPress.com 6.0.2 +Workrave 1.10.44 +Writage +X2Go Client for Windows +XAMPP +XCA +XMake build utility +XMind 10.2.1 +XnView 2.49.4 +XnViewMP 0.97.1 +Yarn +Yinxiang Biji v. 6.20.16 +Yinxiang Biji v. 6.21.10 +Yinxiang Biji v. 6.21.3 +Yinxiang Biji v. 6.21.4 +Yinxiang Biji v. 6.21.9 +YouTube Music Desktop App 1.11.0 +YubiKey Manager +Zentimo PRO 2.3 +ZeroTier One +Zettlr +Zint +Zoom +Zoom Outlook Plugin +Zotero +Zulip +Zulu 3.5.1 +Zygor Client Uninstaller +balenaEtcher 1.5.100 +balenaEtcher 1.5.101 +balenaEtcher 1.5.102 +balenaEtcher 1.5.106 +balenaEtcher 1.5.107 +balenaEtcher 1.5.109 +balenaEtcher 1.5.88 +balenaEtcher 1.5.95 +beatdrop 2.6.2 +bottom +butterflow-ui +calibre 64bit +copytranslator 9.1.0 +darktable +dnGREP 2.9.270 (x64) +draw.io 13.0.3 +dupeGuru 4.0.4 +eM Client +ebbflow +f.lux +ffftp +ghostwriter version 1.7.1 +gnuplot 5.2 patchlevel 8 +grepWin x64 +guinget version 0.1.0.1 +guinget version 0.1.1 +guinget version 0.1.2 +hide.me VPN 3.4.0 +hide.me VPN 3.4.1 +i2pd +iSEEK AnswerWorks English Runtime +iTunes +kdenlive +kdiff3 +mRemoteNG +maxima-5.43.2 +mpv.net version 5.4.8.0 +ndm 1.2.0 (only current user) +nexusfont 2.6 (ver 2.6.2.1870) +ownCloud +pCon.planner PRO +pandoc-plot 0.7.1.0 +pgAdmin 4 version 4.22 +pgAdmin 4 version 4.23 +pgAdmin 4 version 4.26 +pgAdmin 4 version 4.27 +qBittorrent 4.2.5 +qBittorrent 4.3.0 +qBittorrent 4.3.0.1 +remoteit 2.5.32 +remoteit 2.6.2 +sbt 1.3.8 +scilab-6.1.0 (64-bit) +sqlectron 1.31.0 +stretchly 0.21.1 +ueli 8.7.0 +ueli 8.8.1 +ueli 8.9.0 +xmoto 0.6.0 +xmoto 0.6.1 +微软设备健康助手 +支付宝安全控件 5.3.0.3807 +百度网盘 +腾讯QQ diff --git a/Tests/corpus/InputPublishers.txt b/Tests/corpus/InputPublishers.txt new file mode 100644 index 0000000..8086c5f --- /dev/null +++ b/Tests/corpus/InputPublishers.txt @@ -0,0 +1,1137 @@ +Wildfire Games +SweetScape Software +360安全中心 +360安全中心 +Open Media LLC +Open Media LLC +Open Media LLC +Open Media LLC +Open Media LLC +Open Media LLC +Igor Pavlov +Igor Pavlov +Igor Pavlov +Igor Pavlov, Tino Reichardt +Amazon Web Services Developer Relations +Amazon Web Services +AWS Serverless Applications +Axis Communications AB +Abacus Research AG +Microsoft +Microsoft Corporation +Adobe Systems Incorporated +Adobe Systems Incorporated +Adobe Systems Incorporated +AdoptOpenJDK +AdoptOpenJDK +AdoptOpenJDK +AdoptOpenJDK +AdoptOpenJDK +AdoptOpenJDK +AdoptOpenJDK +Famatech +Ondrej Salplachta +Famatech +Pawel Psztyc +Aegisub Team +Aegisub Team +a wandersick +Alacritty +Alchemy Development Group +Algoryx +Stefan Sundin +Amazon.com, Inc. +Amazon +Amazon +Amazon Web Services, Inc +Anaconda, Inc. +Angry IP Scanner +AntiMicro +AppGet +Appium Developers +Appium Developers +Arduino LLC +Armagetron Advanced Team +Sundaram Ramaswamy +Rabid Viper Productions +Audacity Team +CodeUX.design e.U. +Armin Osaj +Lexikos +Lexikos +The Sleuth Kit +GPL Public release. +OmicronLab +7room +Microsoft® Corporation +Microsoft Corporation +Microsoft +Microsoft +Microsoft +Marcin Szeniak +Contoso.com +Beda Kosata +Space Sciences Laboratory, U.C. Berkeley +BPBible Development Team +Google, Inc. +Debauchee Open Source Group +Debauchee Open Source Group +Paul Frazee +Elastic +Elastic +Marco Mastroddi Software +beeftext.org +The Betaflight open source project. +Scooter Software, Inc. +Scooter Software +Scooter Software +Bigly Software +BitPay +Bitwarden Inc. +BleachBit +Blender Foundation +BlueJeans Network, Inc. +Hamster Republic Productions +Apple Inc. +Andrew Sampson +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +brackets.io +Brave Software Inc +Brave Software Inc +TGRMN Software +Buttercup +Buttercup +C-Dogs SDL Team +SingularLabs +Piriform +Canneverbe Limited +Kitware +Corsair +CPUID, Inc. +CPUID, Inc. +CPUID, Inc. +CPUID, Inc. +CPUID, Inc. +Penguin Labs, LLC +SaeraSoft +TechSmith Corporation +TechSmith Corporation +Sindre Sorhus +Sindre Sorhus +Giel Cobben +Mathew Sachin +RedDucks +Alexandr Subbotin +MIT IS&T +secana +Webprofusion Pty Ltd +a wandersick +Chef Software, Inc. +ChemAxon +ChemAxon +ChemAxon +ChemAxon +The Chromium Authors +Circuit Diagram +Circuit Diagram +Cisco Webex LLC +Daniel Scalzi +alch +Fndroid +Fndroid +Fndroid +Fndroid +Beijing EEO Education Technology Co., Ltd. +Clementine +Martin Ridgers +Cloudflare, Inc. +The Code::Blocks Team +Eran Ifrah +Steven Cole +TerranovaTeam +Jay Prall +Toinane +ConEmu-Maximus5 +Concept2 Inc. +Microsoft Corporation +Contasimple S.L. +ALCPU +Couchbase Inc. +Couchbase Inc. +Cozy Cloud +The Cppcheck team +Habib Rehman +cryptomator.org +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +Crystal Dew World +cubicsdr.com +Acro Software Inc. +iterate GmbH +DB Browser for SQLite Team +DBeaver Corp +DBeaver Corp +DBeaver Corp +DBeaver Corp +DBeaver Corp +DBeaver Corp +DBeaver Corp +DBeaver Corp +DBeaver Corp +DJI +DJI +DJI +DJI +DJI +DJI +DJI +DJI +TshwaneDJe +Boxstar +Boxstar +Deezer +Ashley Stone +Piriform +Dell, Inc. +Dell Inc. +Bloodshed Software +Thinking Man Software +Serraniel +Serraniel +Scott Brogden +Dixa +DjVuZone +DockStation +Docker Inc. +Dokany Project +Dokany Project +Dolphin Team +dengine.net +Digimezzo +Doxie & Co. LLC +Dropbox, Inc. +EasternGraphics +EasternGraphics +EagleGet +EagleGet +Luke Stratman +ES-Computing +EduMIPS64 Development Team +Elastic +Elgato Systems GmbH +Empoche.com +Empoche.com +MacPaw, Inc. +a wandersick +Sinew Software Systems Private Limited +The Eraser Project +The Eraser Project +The Eraser Project +The Eraser Project +Esteem +Ethereum +Evernote Corp. +Evernote Corp. +David Carpenter +David Carpenter +David Carpenter +David Carpenter +voidtools +ExpressVPN +Ultrapico +The ExtremeTuxRacer team +Eugene Roshal & Far Group +H.Shirouzu +FastStone Soft +FastStone Soft +Fedora Project +Amine Mouafik +Progress Software Corporation +Progress Software Corporation +Progress Software Corporation +Progress Software Corporation +Progress Software Corporation +Progress Software Corporation +Progress Software Corporation +Adrien Allard +Binary Fortress Software +Tim Kosse +Tim Kosse +Tim Kosse +Tim Kosse +Tim Kosse +Mozilla +Mozilla +Mozilla +Mozilla +OpenSight Software LLC +The FlightGear Team +Dominik Levitsky Studio, LLC +FontForgeBuilds +Free Time +Free Time +Foxit Software Inc. +Foxit Software Inc. +Stefan Malzner +Marek Jasinski - www.FreeCommander.com +Humanity +The GIMP Team +The GIMP Team +The GIMP Team +The GIMP Team +The GIMP Team +The GIMP Team +The GIMP Team +The GIMP Team +ARM Holdings +The Free Software Foundation, Inc. +The GnuPG Project +GCN Development +GOG.com +Artifex Software Inc. +Ghostgum Software Pty Ltd +Garmin Ltd or its subsidiaries +ThoughtWorks Inc. +ThoughtWorks Inc. +The Geany developer team +Primate Labs Inc. +Gephi +Outertech +Git Extensions Team +Git Extensions Team +Git Extensions Team +GitHub, Inc. +The Git Development Community +The Git Development Community +The Git Development Community +The Git Development Community +The Git Development Community +The Git Development Community +GitHub, Inc. +GitHub, Inc. +Stef Heyenrath +Troupe Technology Limited +Glimpse Project +Glimpse Project +Glimpse Project +GnuCash Development Team +GnuCash Development Team +GnuWin32 +GnuWin32 +GnuWin32 +GnuWin32 +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +https://golang.org +GoldWave Inc. +Google LLC +Google Inc. +Google +The Gpg4win Project +The Gpg4win Project +Grafana Labs +Grafana Labs +Grammarly +The Gramps project +Graphcool +Adam Miskiewicz +AT&T Research Labs. +Greenshot +Grid Team +Epiforge Software, LLC +HHD Software, Ltd. +Hector Maurcio Rodriguez Segura +HP Inc. +Huawei Software Technologies Co., Ltd. +Martin Malik - REALiX +Martin Malik - REALiX +Martin Malik - REALiX +Martin Malik - REALiX +HandyOrg +Vincent L +Implbits Software +Implbits Software +JAM Software +Hedgewars Project +Ansgar Becker +Ansgar Becker +Ansgar Becker +Ansgar Becker +Ansgar Becker +Perforce Software, Inc. +IBE Software +HexChat +Scott Lerch +Caphyon +Borvid +Borvid +Borvid +Borvid +Borvid +Borvid +Borvid +Huawei Corporation +Hyne & Son Pty Ltd +Marquis Kurt +Google Inc +Hex-Rays SA +Tibbo Technology Inc +David Moore +IRCCloud Ltd. +Ivan Zahariev +Duong Dieu Phap +Inkscape +jrsoftware.org +jrsoftware.org +Crystal Rich, Ltd +seonglae +Irfan Skiljan +IronPython Team +IronPython Team +ISWIX LLC +Smart Projects +ChemAxon +JabRef +Jackett +Savoir-Faire Linux +Oracle Corporation +Oracle Corporation +JetBrains +Jitsi Team +Jitsi Team +Laurent Cozic +Laurent Cozic +Laurent Cozic +Julia Language +Julia Language +Julia Language +KLCP +KLCP +KKBOX Taiwan Co., Ltd. +Chia-Lung, Chen +Dominik Reichl +Dominik Reichl +Dominik Reichl +KeePassXC Team +KeeWeb +Keybase, Inc. +KiCad +KiCad +KiCad +Krisp Technologies, Inc +Krita Foundation +Roni Lehto +LBRY Inc. +LBRY Inc. +LBRY Inc. +LBRY Inc. +LBRY Inc. +LINE Corporation +Joseph Albahari +LLVM +LMMS Developers +LMMS Developers +love2d.org +leokhoa +LastPass +Lazarus Team +Riot Games, Inc +Lenovo +Lenovo +Lakend Labs, Inc. +Leonflix +BellSoft +BellSoft +BellSoft +BellSoft +BellSoft +BellSoft +BellSoft +BellSoft +LibreCAD Team +The Document Foundation +The Document Foundation +Team Lidarr +Alexey 'Tyrrrz' Golub +Alexey 'Tyrrrz' Golub +Christian Kaiser +Leif Asbrink SM5BSZ +Lisk Foundation +Listen 1 +Listen 1 +Flywheel +Crystal Rich Ltd +Binary Fortress Software +Binary Fortress Software +Logitech Inc. +Loom, Inc. +LyX Team +LyX Team +COTILab +COTILab +Moritz Bunkus +Moritz Bunkus +Moritz Bunkus +Moritz Bunkus +Moritz Bunkus +MPC-HC Team +MPC-HC Team +MPC-HC Team +Thomas Nordquist +Microsoft +Maxthon International Limited +MY.COM B.V. +FlyingSnow, Samantha Glocker +Firetrust +Firetrust +Majsoul Plus Team +GuinpinSoft inc +Malwarebytes +KDE +MariaDB Corporation Ab +Jocs +West Wind Technologies +West Wind Technologies +West Wind Technologies +West Wind Technologies +West Wind Technologies +Markdown Outlook +Master Packager Ltd. +Mattermost, Inc. +MediaArea.net +MediaArea.net +Ventis Media Inc. +The Meld project +Janea Systems +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Garage +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft +Microsoft +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Anaconda, Inc. +Anaconda, Inc. +MongoDB Inc. +Xamarin, Inc. +The MonoGame Team +Moonlight Game Streaming Project +AGALWOOD +AGALWOOD +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Mozilla +Nicholas H.Tollervey +Mullvad VPN +Mullvad VPN +Microsoft Corporation +canonical +The Mumble Developers +The Mumble Developers +The Mumble Developers +Werner Schweer and Others +Youta Tec +Logitech +Martin Renold and the MyPaint Development Team +Oracle Corporation +Feodor2 +Justin Aquadro +Rico Suter +NV Access +NVIDIA Corporation +NVIDIA Corporation +NZXT, Inc. +NZXT, Inc. +NZXT, Inc. +NZXT, Inc. +NZXT, Inc. +NZXT, Inc. +Allan CORNET +Neotys +Lutz Roeder +Nitro +Nmap Project +qinghai +qinghai +qinghai +Node.js Foundation +Nodist +NordVPN +TEFINCOM S.A. +NordVPN +NordVPN +CodingRoad +XhmikosR +Notion Labs, Incorporated +Notion Labs, Incorporated +Nmap Project +NullNoname +Nullsoft and Contributors +OBS Project +Hamster Republic Productions +Ascensio System SIA +GNU Octave +WetHat Lab +Open Shop Channel +The Open-Shell Team +namazso +namazso +ojdkbuild open-source project +ojdkbuild open-source project +ojdkbuild open-source project +ojdkbuild open-source project +OpenMPT Devs +Apache Software Foundation +OpenRA developers +The OpenSCAD Developers +Shining Light Productions +OpenShot Studios, LLC +OpenTTD +OpenTTD +OpenVPN Technologies, Inc. +SparkLabs Pty Ltd +OpenVPN Technologies +Opera Software +Opera Software +Opera Software +Opera Software +Opera Software +Opera Software +Opera Software +Opera Software +Oracle Corporation +Oracle Corporation +Oracle Corporation +Oracle Corporation +OutSystems +EXP Systems LLC +Sober Lemur S.a.s. di Vacondio Andrea +CCPKU +Jan Fiala +NagleCode, LLC +Moonchild Productions +Moonchild Productions +John MacFarlane +John MacFarlane +John MacFarlane +Paradox Interactive +Paragon Software GmbH +Parsec Cloud Inc. +Francesco Sorge +Giorgio Tani +Giorgio Tani +Persepolis Team +Heiko Sommerfeldt +touchbyte GmbH +NGWIN +PicoTorrent contributors. +blupi.org +Sony Interactive Entertainment Network America LLC +Josef Nemec +Plex, Inc. +Plex +Plex, Inc. +Plex, Inc. +Plex, Inc. +Plex, Inc. +www.pokerth.net +Postbox, Inc. +PostgreSQL Global Development Group +PostgreSQL Global Development Group +Microsoft Corporation +Microsoft Corporation +Ironman Software, LLC +Microsoft +Kim Walisch +Private Internet Access, Inc. +Progress Software Corporation +Microsoft Corporation +Proton Technologies AG +Proton Technologies AG +Simon Tatham +Puppet Labs +Puppet Inc +Puppet, Inc. +Puppet Inc +Miller Puckette +Lancaster University Physics +Python Software Foundation +Hubert Pham +Python Software Foundation +Python Software Foundation +Python Software Foundation +Python Software Foundation +Python Software Foundation +Python Software Foundation +Python Software Foundation +Python Software Foundation +QGIS Development Team +QGIS Development Team +QGIS Development Team +Michael Hansen +Hanna Knutsson +LarusStone +Module Art +Paddy Xu +Quicken +R Core Team +R Core Team +R Core Team +RStudio +Rambox +Oleg Danilov +Raspberry Pi +rawtherapee.com +Paul Rawnsley +jklSoft +Devolutions inc. +Devolutions inc. +Remote Mouse +Baldur Karlsson +Antmicro +Responsively +RetroShare Team +VS Revo Group, Ltd. +VS Revo Group, Ltd. +3T Software Labs Ltd +3T Software Labs Ltd +3T Software Labs Ltd +Rocket.Chat Support +Punk Software +Artsoft Entertainment +MarkoBL +code4ward GmbH +Royal Apps GmbH +The R Foundation +RubyInstaller Team +RubyInstaller Team +RubyInstaller Team +Luke Haas +Luke Haas +The Rust Project Developers +The Rust Project Developers +The Rust Project Developers +The Rust Project Developers +The Rust Project Developers +The Rust Project Developers +The Rust Project Developers +The Rust Project Developers +The Rust Project Developers +Topala Software Solutions +Ricardo Villalba +Navimatics LLC +Dotz Softwares +Samsung Electronics Co., Ltd. +mircearoata +Scratch Foundation +Nicke Manarin +The Scribus Team +The ScummVM Team +spikespaz +Sejda BV +Datalust Pty Ltd +Microsoft Corporation +ShareX Team +RandyRants.com +Meltytech, LLC +Sigil-Ebook +Open Whisper Systems +Open Whisper Systems +Open Whisper Systems +Open Whisper Systems +Open Whisper Systems +Open Whisper Systems +Open Whisper Systems +Approximatrix, LLC +Ashley Stone +Skype Technologies S.A. +Skype Technologies S.A. +Skype Technologies S.A. +Slack Technologies +TechSmith Corporation +SnakeNest.com +Cory Plotts +SmartBear Software +Sonic Pi +Sonos, Inc. +Sonos, Inc. +Antoine Aflalo +Atlassian +SpeedCrunch +Spek Project +Standard Notes +Valve Corporation +http://www.sbcl.org +SteelSeries ApS +Stellarium team +Stellarium team +Stellarium team +strawberryperl.com project +General Workings, Inc. +General Workings, Inc. +General Workings, Inc. +Streamlink +Sebastian Meyer +Jan Hovancik +Jan Hovancik +Jan Hovancik +Stride +BrickLink Corporation +Sublime HQ Pty Ltd +Sublime HQ Pty Ltd +Krzysztof Kowalczyk +SuperCollider Community +SuperTuxKart +Microsoft +SyncTrayzor +Mister Group +OpenVPN Technologies, Inc. +erengy +Tailscale Inc. +Tailscale Inc. +Taisei Project +Taskcade Inc. +Taskcade Inc. +"Treasure Data, Inc" +Treasure Data, Inc +Benito van der Zander +TeX Users Group +TeamSpeak Systems GmbH +TechPowerUp +Telegram FZ-LLC +Telegram FZ-LLC +Telegram FZ-LLC +Telegram FZ-LLC +Telegram FZ-LLC +Telegram FZ-LLC +Telegram FZ-LLC +Telegram FZ-LLC +Telegram FZ-LLC +TeraTerm Project +Eugene Pankov +Eugene Pankov +Eugene Pankov +CompuPhase +Tesseract-OCR community +Texmaker +Texnomic +RaMMicHaeL +Appest.com +GlavSoft LLC. +TikzEdt +mapeditor.org +Nadeo +Toggl +Toggl +TortoiseGit +TortoiseSVN +TortoiseSVN +TranslucentTB Open Source Developers +Transmission Project +Yury Sidorov & Transmission Remote GUI working group +Binary Fortress Software +Binary Fortress Software +JAM Software +JAM Software +Trelby.org +Cerulean Studios, LLC +TunnelBear +New Breed Software +Inspect Element Inc. +Xander Frangos +Twitch Interactive, Inc. +G DATA CyberDefense AG +SafelyRemove.com +Drew Naylor +Drew Naylor +Ultimaker B.V. +Ultimaker B.V. +Ultimaker B.V. +uvnc bvba +Reason Software Company Inc. +Unified Intents AB +Unity Technologies Inc. +Microsoft Corporation +Microsoft Corporation +Ubisoft +UMEZAWA Takeshi +VCV +VideoLAN +VideoLAN +VideoLAN +VMware, Inc. +VMware, Inc. +VMware, Inc. +RealVNC Ltd +RealVNC Ltd +Microsoft Corporation +Microsoft Corporation +marha@users.sourceforge.net +Bram Moolenaar et al. +Virt Manager Project +Vivaldi Technologies AS. +Black Tree Gaming Ltd. +VoyagerX, Inc. +LunarG, Inc. +Warzone 2100 Project +Waterfox +Waterfox +Waterfox +Devolutions Inc. +Buds +Buds +Buds +Buds +Machine Learning Group, University of Waikato, Hamilton, NZ +ImageWriter Developers +Sam Hocevar +Timothy Johnson +Timothy Johnson +Timothy Johnson +Navimatics LLC +HTTrack +Thingamahoochie Software +win.rar GmbH +win.rar GmbH +Martin Prikryl +Corel Corporation +Winamp SA +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Dynastream Innovations, Inc. +Silicon Labs Software +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +Microsoft Corporation +WireGuard LLC +The Wireshark developer community, https://www.wireshark.org +The Wireshark developer community, https://www.wireshark.org +The Wireshark developer community, https://www.wireshark.org +The Wireshark developer community, https://www.wireshark.org +Antibody Software +Antibody Software +Antibody Software +Antibody Software +Antibody Software +Automattic Inc. +Automattic Inc. +Automattic Inc. +Automattic Inc. +Rob Caelers & Raymond Penners +Writage +X2Go Project +Bitnami +Christian Hohnstaedt +The TBOOX Open Source Group +XMind Ltd. +Gougelet Pierre-e +Gougelet Pierre-e +Yarn Contributors +Beijing Yinxiang Biji Technologies Co., Ltd. +Beijing Yinxiang Biji Technologies Co., Ltd. +Beijing Yinxiang Biji Technologies Co., Ltd. +Beijing Yinxiang Biji Technologies Co., Ltd. +Beijing Yinxiang Biji Technologies Co., Ltd. +Adler Luiz +Yubico AB +Zentimo.com +ZeroTier, Inc. +Hendrik Erz +Robin Stuart & BogDan Vatra +Zoom +Zoom +Corporation for Digital Scholarship +Kandra Labs, Inc. +Sangoma Technologies Corp. +Zygor Guides +Balena Inc. +Balena Inc. +Balena Inc. +Balena Inc. +Balena Inc. +Balena Inc. +Balena Inc. +Balena Inc. +Nathaniel Johns +Clement Tsang +butterflow-ui @ github +Kovid Goyal +Elliott Zheng +the darktable project +dnGrep Community Contributors +JGraph +Hardcoded Software +eM Client Inc. +Ebbflow.io +f.lux Software LLC +Kurata Sayuri +wereturtle +gnuplot development team +Stefans Tools +Drew Naylor +Drew Naylor +Drew Naylor +eVenture Limited +eVenture Limited +PurpleI2P +Vantage Linguistics +Apple Inc. +KDE e.V. +KDE e.V. +Next Generation Software +Maxima Team +Frank Skare (stax76) +720kb +xiles +ownCloud GmbH +EasternGraphics +Laurent P. Ren© de Cotret +The pgAdmin Development Team +The pgAdmin Development Team +The pgAdmin Development Team +The pgAdmin Development Team +The qBittorrent project +The qBittorrent project +The qBittorrent project +remote.it +remote.it +Lightbend, Inc. +Scilab Enterprises +The Sqlectron Team +Jan Hovancik +Oliver Schwendener +Oliver Schwendener +Oliver Schwendener +Humanity +Humanity +Microsoft Corporation +Alipay.com Co., Ltd. +百度在线网络技术(北京)有限公司 +腾讯科技(深圳)有限公司 diff --git a/Tests/corpus/NormalizationInitialIds.txt b/Tests/corpus/NormalizationInitialIds.txt new file mode 100644 index 0000000..97b681f --- /dev/null +++ b/Tests/corpus/NormalizationInitialIds.txt @@ -0,0 +1,1137 @@ +WildfireGames.0AD +SweetScapeSoftware.010Editor +360安全中心.360安全卫士 +360安全中心.360杀毒 +OpenMedia.4KSlideshowMaker +OpenMedia.4KStogram +OpenMedia.4KVideoDownloader +OpenMedia.4KVideoDownloader +OpenMedia.4KVideotoMP3 +OpenMedia.4KYouTubetoMP3 +IgorPavlov.7Zip +IgorPavlov.7Zip +IgorPavlov.7Zipalpha +IgorPavlovTinoReichardt.7ZipZSZS +AmazonWebServicesDeveloperRelations.AWSCommandLineInterface +AmazonWebServices.AWSCommandLineInterface +AWSServerlessApplications.AWSSAMCommandLineInterface +AxisCommunications.AXISCameraStation +AbacusResearch.AbaClient +Microsoft.AccessibilityInsightsForWindows +Microsoft.ActiveDirectoryAuthenticationLibraryforSQLServer +AdobeSystems.AdobeAcrobatReaderDCCzech +AdobeSystems.AdobeAcrobatReaderDC +AdobeSystems.AdobeAcrobatReaderDCMUI +AdoptOpenJDK.AdoptOpenJDKJDKwithHotspot +AdoptOpenJDK.AdoptOpenJDKJDKwithHotspot +AdoptOpenJDK.AdoptOpenJDKJDKwithHotspot +AdoptOpenJDK.AdoptOpenJDKJDKwithHotspot +AdoptOpenJDK.AdoptOpenJDKJDKwithHotspot +AdoptOpenJDK.AdoptOpenJDKJDKwithHotspot +AdoptOpenJDK.AdoptOpenJDKJDKwithHotspot +Famatech.AdvancedIPScanner +OndrejSalplachta.AdvancedLogViewer +Famatech.AdvancedPortScanner +PawelPsztyc.AdvancedRestClient +AegisubTeam.Aegisub8975master8d77da3 +AegisubTeam.Aegisub +awandersick.AeroZoombeta2 +Alacritty.Alacritty +AlchemyDevelopmentGroup.AlchemyBeta +Algoryx.Algodoo +StefanSundin.AltDrag +Amazoncom.AmazonChime +Amazon.AmazonCorretto +Amazon.AmazonCorretto8 +AmazonWebServices.AmazonWorkSpaces +Anaconda.Anaconda3 +AngryIPScanner.AngryIPScanner +AntiMicro.AntiMicro +AppGet.AppGet +AppiumDevelopers.Appium +AppiumDevelopers.Appium +Arduino.Arduino +ArmagetronAdvancedTeam.ArmagetronAdvanced +SundaramRamaswamy.Artha +RabidViperProductions.AssaultCube +AudacityTeam.Audacity +CodeUXdesigneU.AuthPass +ArminOsaj.AutoDarkMode +Lexikos.AutoHotkey +Lexikos.AutoHotkey +TheSleuthKit.Autopsy +GPLPublicrelease.AviSynth +OmicronLab.AvroKeyboard +7room.Aya +Microsoft.AzureCosmosDBEmulator +Microsoft.AzureDataStudio +Microsoft.AzureFunctionsCoreTools +Microsoft.AzureIoTExplorer +Microsoft.AzureIoTexplorer +MarcinSzeniak.BCUninstaller +Contosocom.BITSManager +BedaKosata.BKChem +SpaceSciencesLaboratoryUCBerkeley.BOINC +BPBibleDevelopmentTeam.BPBible +Google.BackupandSyncfromGoogle +DebaucheeOpenSourceGroup.Barrier +DebaucheeOpenSourceGroup.Barrier +PaulFrazee.BeakerBrowser +Elastic.Beatswinlogbeat +Elastic.Beatswinlogbeat +MarcoMastroddiSoftware.BeeBEEP +beeftextorg.Beeftext +TheBetaflightopensourceproject.BetaflightConfigurator +ScooterSoftware.BeyondCompare4 +ScooterSoftware.BeyondCompare +ScooterSoftware.BeyondCompare +BiglySoftware.BiglyBT +BitPay.BitPay +Bitwarden.Bitwarden +BleachBit.BleachBit +BlenderFoundation.Blender +BlueJeansNetwork.BlueJeans +HamsterRepublicProductions.BobtheHamsterVGA +Apple.Bonjour +AndrewSampson.BorderlessGaming +Microsoft.BotFrameworkComposer +Microsoft.BotFrameworkComposer +Microsoft.BotFrameworkComposer +Microsoft.BotFrameworkComposer +Microsoft.BotFrameworkEmulator +Microsoft.BotFrameworkEmulator +Microsoft.BotFrameworkEmulator +bracketsio.Brackets +BraveSoftware.Brave +BraveSoftware.BraveNightly +TGRMNSoftware.BulkRenameUtility +Buttercup.Buttercup +Buttercup.Buttercup +CDogsSDLTeam.CDogsSDL +SingularLabs.CCEnhancer +Piriform.CCleaner +Canneverbe.CDBurnerXP +Kitware.CMake +Corsair.CORSAIRiCUESoftware +CPUID.CPUIDCPUZ +CPUID.CPUIDCPUZ +CPUID.CPUIDCPUZ +CPUID.CPUIDHWMonitor +CPUID.CPUIDHWMonitor +PenguinLabs.Cacher +SaeraSoft.CaesiumPH +TechSmith.Camtasia2019 +TechSmith.Camtasia2020 +SindreSorhus.Caprine +SindreSorhus.Caprine +GielCobben.Caption +MathewSachin.Captura +RedDucks.CemUI +AlexandrSubbotin.Cerebro +MITIST.CertAidforWindows +secana.CertDump +Webprofusion.CertifyTheWeb +awandersick.ChMac +ChefSoftware.ChefDK +ChemAxon.ChemAxonChemCurator +ChemAxon.ChemAxonMarkushEditor +ChemAxon.ChemAxonMarvinSuite +ChemAxon.ChemAxonMarvinSuite +TheChromiumAuthors.Chromium +CircuitDiagram.CircuitDiagram +CircuitDiagram.CircuitDiagram +CiscoWebex.CiscoWebexMeetings +DanielScalzi.CitycraftLauncher +alch.ClamWinFreeAntivirus +Fndroid.ClashforWindows +Fndroid.ClashforWindows +Fndroid.ClashforWindows +Fndroid.ClashforWindows +BeijingEEOEducationTechnology.ClassIn +Clementine.Clementine +MartinRidgers.Clink +Cloudflare.CloudflareWARP +TheCodeBlocksTeam.CodeBlocks +EranIfrah.CodeLite +StevenCole.Coffee +TerranovaTeam.ColobotGoldEditionalpha +JayPrall.ColorCop +Toinane.Colorpicker +ConEmuMaximus.ConEmu201011 +Concept2.Concept2Utility +Microsoft.ConfigMgr2012Toolkit +Contasimple.ContasimpleDesktop +ALCPU.CoreTemp +Couchbase.CouchbaseServerCommunityEdition +Couchbase.CouchbaseServerEnterpriseEdition +CozyCloud.CozyDrive +TheCppcheckteam.Cppcheck +HabibRehman.Crypter +cryptomatororg.Cryptomator +CrystalDewWorld.CrystalDiskInfo +CrystalDewWorld.CrystalDiskInfo +CrystalDewWorld.CrystalDiskInfoKureiKeiEdition +CrystalDewWorld.CrystalDiskInfoShizukuEdition +CrystalDewWorld.CrystalDiskInfo +CrystalDewWorld.CrystalDiskInfo +CrystalDewWorld.CrystalDiskInfoKureiKeiEdition +CrystalDewWorld.CrystalDiskInfoShizukuEdition +CrystalDewWorld.CrystalDiskInfo +CrystalDewWorld.CrystalDiskInfo +CrystalDewWorld.CrystalDiskInfoKureiKeiEdition +CrystalDewWorld.CrystalDiskInfoShizukuEdition +CrystalDewWorld.CrystalDiskInfo +CrystalDewWorld.CrystalDiskInfoKureiKeiEdition +CrystalDewWorld.CrystalDiskInfoShizukuEdition +CrystalDewWorld.CrystalDiskMark +CrystalDewWorld.CrystalDiskMarkShizukuEdition +cubicsdrcom.CubicSDRInstaller +AcroSoftware.CutePDFWriter +iterate.Cyberduck +DBBrowserforSQLiteTeam.DBBrowserforSQLite +DBeaver.DBeaver +DBeaver.DBeaver +DBeaver.DBeaver +DBeaver.DBeaver +DBeaver.DBeaver +DBeaver.DBeaver +DBeaver.DBeaver +DBeaver.DBeaver +DBeaver.DBeaver +DJI.DJIAssistant2 +DJI.DJIAssistant2ForAeroscope +DJI.DJIAssistant2ForAutopilot +DJI.DJIAssistant2ForBatteryStation +DJI.DJIAssistant2ForMG +DJI.DJIAssistant2ForMatrice +DJI.DJIAssistant2ForMavic +DJI.DJIAssistant2ForPhantom +TshwaneDJe.DaveGnukem +Boxstar.DeepVocalToolBoxbetaversionbeta +Boxstar.DeepVocalbetaversionbeta +Deezer.Deezer +AshleyStone.DefaultAudio +Piriform.Defraggler +Dell.DellCommandUpdate +Dell.DellUpdate +BloodshedSoftware.DevC +ThinkingManSoftware.Dimension4 +Serraniel.DiscordMediaLoader +Serraniel.DiscordMediaLoader +ScottBrogden.Ditto +Dixa.Dixa +DjVuZone.DjVuLibreDjView +DockStation.DockStation +Docker.DockerDesktop +DokanyProject.DokanLibrary +DokanyProject.DokanLibrary +DolphinTeam.Dolphin +denginenet.Doomsday +Digimezzo.Dopamine +Doxie.Doxie +Dropbox.Dropbox +EasternGraphics.EGRSafenetActivation +EasternGraphics.EGRShellExtension +EagleGet.EagleGet +EagleGet.EagleGet +LukeStratman.EasyConnect +ESComputing.EditPlus +EduMIPS64DevelopmentTeam.EduMIPS64 +Elastic.Elasticsearch +ElgatoSystems.ElgatoStreamDeck +Empochecom.Empoche +Empochecom.Empoche +MacPaw.Encrypto +awandersick.EnglishizeCmd +SinewSoftwareSystemsPrivate.Enpass +TheEraserProject.Eraser +TheEraserProject.Eraser +TheEraserProject.Eraser +TheEraserProject.Eraser +Esteem.Esteem +Ethereum.EthereumGethOfficialGoimplementationoftheEthereumprotocol +Evernote.Evernotev +Evernote.Evernotev +DavidCarpenter.Everything +DavidCarpenter.Everything +DavidCarpenter.Everything +DavidCarpenter.EverythingLite +voidtools.Everything +ExpressVPN.ExpressVPN +Ultrapico.Expresso +TheExtremeTuxRacerteam.ExtremeTuxRacer +EugeneRoshalFarGroup.FarManager3 +HShirouzu.FastCopy +FastStoneSoft.FastStoneCapture +FastStoneSoft.FastStoneImageViewer +FedoraProject.FedoraMediaWriter +AmineMouafik.Ferdi +ProgressSoftware.FiddlerEverywhere +ProgressSoftware.FiddlerEverywhere +ProgressSoftware.FiddlerEverywhere +ProgressSoftware.FiddlerEverywhere +ProgressSoftware.FiddlerEverywhere +ProgressSoftware.FiddlerEverywhere +ProgressSoftware.FiddlerEverywhere +AdrienAllard.FileConverter +BinaryFortressSoftware.FileSeek +TimKosse.FileZillaClient +TimKosse.FileZillaClient +TimKosse.FileZillaClient +TimKosse.FileZillaClient +TimKosse.FileZillaClient +Mozilla.FirefoxDeveloperEdition +Mozilla.FirefoxDeveloperEdition +Mozilla.FirefoxDeveloperEdition +Mozilla.FirefoxDeveloperEdition +OpenSightSoftware.FlashFXP5 +TheFlightGearTeam.FlightGear +DominikLevitskyStudio.FontBase +FontForgeBuilds.FontForge +FreeTime.FormatFactory +FreeTime.FormatFactory +FoxitSoftware.FoxitPhantomPDF +FoxitSoftware.FoxitReader +StefanMalzner.Franz +MarekJasinskiwwwFreeCommandercom.FreeCommanderXE +Humanity.FreeMat +TheGIMPTeam.GIMP +TheGIMPTeam.GIMP +TheGIMPTeam.GIMP +TheGIMPTeam.GIMP +TheGIMPTeam.GIMP +TheGIMPTeam.GIMP +TheGIMPTeam.GIMP +TheGIMPTeam.GIMP +ARM.GNUArmEmbeddedToolchain92020 +TheFreeSoftwareFoundation.GNUMidnightCommander +TheGnuPGProject.GNUPrivacyGuard +GCNDevelopment.GNURadio +GOGcom.GOGGALAXY +ArtifexSoftware.GPLGhostscript +GhostgumSoftware.GSview +Garmin.GarminExpress +ThoughtWorks.Gauge +ThoughtWorks.Gauge +TheGeanydeveloperteam.Geany +PrimateLabs.Geekbench5 +Gephi.Gephi +Outertech.GetDiz +GitExtensionsTeam.GitExtensions +GitExtensionsTeam.GitExtensions +GitExtensionsTeam.GitExtensions +GitHub.GitLFS +TheGitDevelopmentCommunity.Git +TheGitDevelopmentCommunity.Git +TheGitDevelopmentCommunity.Git +TheGitDevelopmentCommunity.Git +TheGitDevelopmentCommunity.Git +TheGitDevelopmentCommunity.Git +GitHub.GitHubCLI +GitHub.GitHubDesktopMachineWideInstaller +StefHeyenrath.GitHubReleaseNotes +TroupeTechnology.Gitter +GlimpseProject.Glimpse +GlimpseProject.Glimpse +GlimpseProject.Glimpse +GnuCashDevelopmentTeam.GnuCash +GnuCashDevelopmentTeam.GnuCash +GnuWin.GnuWin32Grep +GnuWin.GnuWin32Make +GnuWin.GnuWin32Wget +GnuWin.GnuWin32Zip +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +golangorg.GoProgrammingLanguagego +GoldWave.GoldWave +Google.GoogleChrome +Google.GoogleCloudSDK +Google.GoogleEarthPro +TheGpg4winProject.Gpg4win +TheGpg4winProject.Gpg4win +GrafanaLabs.GrafanaEnterprise +GrafanaLabs.GrafanaOSS +Grammarly.GrammarlyforMicrosoftOfficeSuite +TheGrampsproject.GrampsAIO64 +Graphcool.GraphQLPlayground +AdamMiskiewicz.GraphiQL +ATTResearchLabs.Graphviz +Greenshot.Greenshot +GridTeam.Grid +EpiforgeSoftware.Grindstone4 +HHDSoftware.HHDSoftwareFreeHexEditorNeo +HectorMaurcioRodriguezSegura.HMNISEdit +HP.HPCloudRecoveryTool +HuaweiSoftwareTechnologies.HUAWEICloud +MartinMalikREALiX.HWiNFO64 +MartinMalikREALiX.HWiNFO64 +MartinMalikREALiX.HWiNFO64 +MartinMalikREALiX.HWiNFO64 +HandyOrg.HandyWinGet +VincentL.Harmony +ImplbitsSoftware.HashTab +ImplbitsSoftware.HashTab +JAMSoftware.HeavyLoad +HedgewarsProject.Hedgewars +AnsgarBecker.HeidiSQL +AnsgarBecker.HeidiSQL +AnsgarBecker.HeidiSQL +AnsgarBecker.HeidiSQL +AnsgarBecker.HeidiSQL +PerforceSoftware.HelixCoreApps +IBESoftware.HelpNDocPersonalEdition +HexChat.HexChat +ScottLerch.HostsFileEditor +Caphyon.Hover +Borvid.HttpMasterExpressEdition +Borvid.HttpMasterExpressEdition +Borvid.HttpMasterExpressEdition +Borvid.HttpMasterExpressEdition +Borvid.HttpMasterProfessionalEdition +Borvid.HttpMasterProfessionalEdition +Borvid.HttpMasterProfessionalEdition +Huawei.HuaweiQuickAppIDE +HyneSon.HyneTimberDesign +MarquisKurt.HyperspaceDesktop +Google.IAPDesktop +HexRays.IDAFreeware +TibboTechnology.IONinja3 +DavidMoore.IPFilter +IRCCloud.IRCCloud +IvanZahariev.IZArc +DuongDieuPhap.ImageGlass +Inkscape.Inkscape +jrsoftwareorg.InnoSetup +jrsoftwareorg.InnoSetup +CrystalRich.InternetOff +seonglae.Intuiter +IrfanSkiljan.IrfanView +IronPythonTeam.IronPython +IronPythonTeam.IronPython +ISWIX.IsWiX +SmartProjects.IsoBuster +ChemAxon.JChemNETAPI +JabRef.JabRef +Jackett.Jackett +SavoirFaireLinux.Jami +Oracle.Java8Update251 +Oracle.Java8Update261 +JetBrains.JetBrainsToolbox +JitsiTeam.JitsiMeet +JitsiTeam.JitsiMeet +LaurentCozic.Joplin +LaurentCozic.Joplin +LaurentCozic.Joplin +JuliaLanguage.Julia +JuliaLanguage.Julia +JuliaLanguage.Julia +KLCP.KLiteCodecPackStandard +KLCP.KLiteMegaCodecPack +KKBOXTaiwan.KKBOX +ChiaLungChen.Kaku +DominikReichl.KeePassPasswordSafe +DominikReichl.KeePassPasswordSafe +DominikReichl.KeePassPasswordSafe +KeePassXCTeam.KeePassXC +KeeWeb.KeeWeb +Keybase.Keybase +KiCad.KiCad +KiCad.KiCad +KiCad.KiCad +KrispTechnologies.Krisp +KritaFoundation.Krita +RoniLehto.LMath +LBRY.LBRY +LBRY.LBRY +LBRY.LBRY +LBRY.LBRY +LBRY.LBRY +LINE.LINE +JosephAlbahari.LINQPad6 +LLVM.LLVM +LMMSDevelopers.LMMS +LMMSDevelopers.LMMS +love2dorg.LOVE +leokhoa.Laragon +LastPass.LastPass +LazarusTeam.Lazarus +RiotGames.LeagueofLegends +Lenovo.LenovoMigrationAssistant +Lenovo.LenovoSystemUpdate +LakendLabs.Lens +Leonflix.Leonflix +BellSoft.LibericaJDK11 +BellSoft.LibericaJDK11Full +BellSoft.LibericaJDK14 +BellSoft.LibericaJDK14Full +BellSoft.LibericaJDK15 +BellSoft.LibericaJDK15Full +BellSoft.LibericaJDK8 +BellSoft.LibericaJDK8Full +LibreCADTeam.LibreCAD +TheDocumentFoundation.LibreOffice +TheDocumentFoundation.LibreOffice +TeamLidarr.Lidarr +AlexeyTyrrrzGolub.LightBulb +AlexeyTyrrrzGolub.LightBulb +ChristianKaiser.Lightscreen +LeifAsbrinkSM5BSZ.Linrad +LiskFoundation.LiskHub +Listen.Listen1 +Listen.Listen1 +Flywheel.Local +CrystalRich.LockHunter +BinaryFortressSoftware.LogFusion +BinaryFortressSoftware.LogFusion +Logitech.LogitechGamingSoftware +Loom.Loom +LyXTeam.LyX +LyXTeam.LyX +COTILab.MCXStudioversionnightlybuild +COTILab.MCXStudio +MoritzBunkus.MKVToolNix +MoritzBunkus.MKVToolNix +MoritzBunkus.MKVToolNix +MoritzBunkus.MKVToolNix +MoritzBunkus.MKVToolNix +MPCHCTeam.MPCHC +MPCHCTeam.MPCHC +MPCHCTeam.MPCHC +ThomasNordquist.MQTTExplorer +Microsoft.MSIXCore +MaxthonInternational.MX5 +MYCOM.MYGAMESGameCenter +FlyingSnowSamanthaGlocker.MacType +Firetrust.MailWasher +Firetrust.MailWasherPro +MajsoulPlusTeam.MajsoulPlus +GuinpinSoft.MakeMKV +Malwarebytes.Malwarebytes +KDE.Marble +MariaDB.MariaDB +Jocs.MarkText +WestWindTechnologies.MarkdownMonster +WestWindTechnologies.MarkdownMonster +WestWindTechnologies.MarkdownMonster +WestWindTechnologies.MarkdownMonster +WestWindTechnologies.MarkdownMonster +MarkdownOutlook.MarkdownOutlook +MasterPackager.MasterPackager +Mattermost.Mattermost +MediaAreanet.MediaInfo +MediaAreanet.MediaInfoCLI +VentisMedia.MediaMonkey +TheMeldproject.Meld +JaneaSystems.MemuraiDeveloper +Microsoft.MicrosoftNETCoreSDK +Microsoft.MicrosoftNETCoreSDK +Microsoft.MicrosoftNETCoreSDK +Microsoft.MicrosoftNETCoreSDK +Microsoft.MicrosoftNETCoreSDK +Microsoft.MicrosoftNETCoreSDK +Microsoft.MicrosoftNETFrameworkMultiTargetingPack +Microsoft.MicrosoftNETFrameworkMultiTargetingPack +Microsoft.MicrosoftNETFrameworkMultiTargetingPack +Microsoft.MicrosoftNETFrameworkSDK +Microsoft.MicrosoftNETFrameworkMultiTargetingPack +Microsoft.MicrosoftNETFrameworkMultiTargetingPack +Microsoft.MicrosoftNETFrameworkSDK +Microsoft.MicrosoftNETFrameworkTargetingPack +Microsoft.MicrosoftNETFrameworkSDK +Microsoft.MicrosoftNETFrameworkTargetingPack +Microsoft.MicrosoftNETSDK +Microsoft.MicrosoftNETSDK +Microsoft.MicrosoftNETSDK +Microsoft.MicrosoftNETSDK +Microsoft.MicrosoftAzureCLI +Microsoft.MicrosoftAzureStorageEmulator +Microsoft.MicrosoftAzureStorageExplorer +Microsoft.MicrosoftAzureStorageExplorer +Microsoft.MicrosoftDeploymentToolkit +Microsoft.MicrosoftEdge +Microsoft.MicrosoftEdgeBeta +Microsoft.MicrosoftEdgeDev +MicrosoftGarage.MicrosoftGarageMousewithoutBorders +Microsoft.MicrosoftHelpViewer +Microsoft.MicrosoftHelpViewer +Microsoft.MicrosoftMPI +Microsoft.MicrosoftMPI +Microsoft.MicrosoftMPISDK +Microsoft.MicrosoftODBCDriver13forSQLServer +Microsoft.MicrosoftODBCDriver17forSQLServer +Microsoft.MicrosoftOLEDBDriverforSQLServer +Microsoft.MicrosoftROpen +Microsoft.MicrosoftROpen +Microsoft.MicrosoftSQLServer2012NativeClient +Microsoft.MicrosoftSQLServer2014ManagementObjects +Microsoft.MicrosoftSQLServer2016 +Microsoft.MicrosoftSQLServer2016Policies +Microsoft.MicrosoftSQLServer2016TSQLLanguageService +Microsoft.MicrosoftSQLServer2016TSQLScriptDom +Microsoft.MicrosoftSQLServer2017 +Microsoft.MicrosoftSQLServer2017Policies +Microsoft.MicrosoftSQLServer2017TSQLLanguageService +Microsoft.MicrosoftSQLServerDataTierApplicationFramework +Microsoft.MicrosoftSQLServerManagementStudio +Microsoft.MicrosoftSQLServerManagementStudio +Microsoft.MicrosoftSQLServerManagementStudio +Microsoft.MicrosoftSQLServerManagementStudio +Microsoft.MicrosoftSQLServerManagementStudio +Microsoft.MicrosoftSmallBasic +Microsoft.MicrosoftSystemCLRTypesforSQLServer2014 +Microsoft.MicrosoftSystemCLRTypesforSQLServer2016 +Microsoft.MicrosoftSystemCLRTypesforSQLServer2017 +Microsoft.MicrosoftVisioViewer2016 +Microsoft.MicrosoftVisualStudio2010ToolsforOfficeRuntime +Microsoft.MicrosoftVisualStudio2015Shell +Microsoft.MicrosoftVisualStudioCode +Microsoft.MicrosoftVisualStudioCodeInsiders +Microsoft.MicrosoftVisualStudioToolsforApplications2015 +Microsoft.MicrosoftVisualStudioToolsforApplications2015LanguageSupport +Microsoft.MicrosoftVisualStudioToolsforApplications2017 +Microsoft.MicrosoftWebPlatformInstaller +Anaconda.Miniconda3 +Anaconda.Miniconda3py +MongoDB.MongoDB2008PlusSSL +Xamarin.MonoforWindows +TheMonoGameTeam.MonoGameSDK +MoonlightGameStreamingProject.MoonlightGameStreamingClient +AGALWOOD.Motrix +AGALWOOD.Motrix +Mozilla.MozillaFirefoxESR +Mozilla.MozillaFirefoxESR +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefoxESR +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefoxESR +Mozilla.MozillaFirefoxESR +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaFirefox +Mozilla.MozillaMaintenanceService +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +Mozilla.MozillaThunderbird +NicholasHTollervey.Mu +MullvadVPN.MullvadVPN +MullvadVPN.MullvadVPN +Microsoft.MultilingualAppToolkit +canonical.Multipass +TheMumbleDevelopers.Mumble +TheMumbleDevelopers.Mumble +TheMumbleDevelopers.Mumble +WernerSchweerandOthers.MuseScore3 +YoutaTec.Muta +Logitech.MyHarmony +MartinRenoldandtheMyPaintDevelopmentTeam.MyPaint +Oracle.MySQLInstallerCommunity +Feodor.Mypal +JustinAquadro.NBTExplorer +RicoSuter.NSwagStudio +NVAccess.NVDA +NVIDIA.NVIDIANVIDIARTXVoiceDriver +NVIDIA.NVIDIARTXVoiceApplication +NZXT.NZXTCAM +NZXT.NZXTCAM +NZXT.NZXTCAM +NZXT.NZXTCAM +NZXT.NZXTCAM +NZXT.NZXTCAM +AllanCORNET.Nelson +Neotys.NeoLoad +LutzRoeder.Netron +Nitro.NitroPro +NmapProject.Nmap +qinghai.NoSQLBoosterforMongoDB +qinghai.NoSQLBoosterforMongoDB +qinghai.NoSQLBoosterforMongoDB +NodejsFoundation.Nodejs +Nodist.Nodist +NordVPN.NordVPN +TEFINCOM.NordVPN +NordVPN.NordVPNnetworkTAP +NordVPN.NordVPNnetworkTUN +CodingRoad.NoteHighlight2016 +XhmikosR.Notepad2mod +NotionLabs.Notion +NotionLabs.Notion +NmapProject.Npcap +NullNoname.NullpoMino +NullsoftandContributors.NullsoftInstallSystem +OBSProject.OBSStudio +HamsterRepublicProductions.OHRRPGCEgorgonzola20200502 +AscensioSystemSIA.ONLYOFFICEDesktopEditors +GNUOctave.Octave +WetHatLab.OneNoteTaggingKit +OpenShopChannel.OpenShopChannelDownloader +TheOpenShellTeam.OpenShell +namazso.OpenHashTab +namazso.OpenHashTab +ojdkbuildopensourceproject.OpenJDK +ojdkbuildopensourceproject.OpenJDK +ojdkbuildopensourceproject.OpenJDK +ojdkbuildopensourceproject.OpenJDK +OpenMPTDevs.OpenMPT +ApacheSoftwareFoundation.OpenOffice +OpenRAdevelopers.OpenRA +TheOpenSCADDevelopers.OpenSCAD +ShiningLightProductions.OpenSSL +OpenShotStudios.OpenShotVideoEditor +OpenTTD.OpenTTD +OpenTTD.OpenTTD +OpenVPNTechnologies.OpenVPN +SparkLabs.OpenVPNConfigurationGenerator +OpenVPNTechnologies.OpenVPNConnect +OperaSoftware.OperaGXStable +OperaSoftware.OperaGXStable +OperaSoftware.OperaStable +OperaSoftware.OperaStable +OperaSoftware.OperaStable +OperaSoftware.OperaStable +OperaSoftware.OperaStable +OperaSoftware.OperaStable +Oracle.OracleVMVirtualBox +Oracle.OracleVMVirtualBox +Oracle.OracleVMVirtualBox +Oracle.OracleVMVirtualBox +OutSystems.OutSystemsDevelopmentEnvironment11 +EXPSystems.PDFreDirect +SoberLemurSasdiVacondioAndrea.PDFsamBasic +CCPKU.PKUGateway +JanFiala.PSPadeditor +NagleCode.PacketSender +MoonchildProductions.PaleMoon +MoonchildProductions.PaleMoon +JohnMacFarlane.Pandoc +JohnMacFarlane.Pandoc +JohnMacFarlane.Pandoc +ParadoxInteractive.ParadoxLauncher +ParagonSoftware.ParagonBackupRecoveryÃâžÂ17CE +ParsecCloud.Parsec +FrancescoSorge.PasteIntoFile +GiorgioTani.PeaZip +GiorgioTani.PeaZip +PersepolisTeam.PersepolisDownloadManager +HeikoSommerfeldt.PhonerLite +touchbyte.PhotoSync +NGWIN.PicPick +PicoTorrentcontributors.PicoTorrent +blupiorg.PlanetBlupi +SonyInteractiveEntertainmentNetworkAmerica.PlayStationÃâžÂNow +JosefNemec.Playnite +Plex.Plex +Plex.PlexMediaPlayer +Plex.PlexMediaServer +Plex.Plexamp +Plex.Plexamp +Plex.Plexamp +wwwpokerthnet.PokerTH +Postbox.Postbox +PostgreSQLGlobalDevelopmentGroup.PostgreSQL12 +PostgreSQLGlobalDevelopmentGroup.PostgreSQL13 +Microsoft.PowerShell7preview +Microsoft.PowerShell7 +IronmanSoftware.PowerShellUniversal +Microsoft.PowerToys +KimWalisch.Primesieve +PrivateInternetAccess.PrivateInternetAccess +ProgressSoftware.ProgressTelerikFiddler +Microsoft.ProjectMyScreenApp +ProtonTechnologies.ProtonVPN +ProtonTechnologies.ProtonVPNTap +SimonTatham.PuTTY +PuppetLabs.Puppet +Puppet.PuppetAgent +Puppet.PuppetBolt +Puppet.PuppetDevelopmentKit +MillerPuckette.PureData +LancasterUniversityPhysics.PyMODA +PythonSoftwareFoundation.Python +HubertPham.PythonPyAudio +PythonSoftwareFoundation.Python +PythonSoftwareFoundation.Python +PythonSoftwareFoundation.Python +PythonSoftwareFoundation.Python +PythonSoftwareFoundation.Python +PythonSoftwareFoundation.Python +PythonSoftwareFoundation.Python +PythonSoftwareFoundation.PythonLauncher +QGISDevelopmentTeam.QGISACoru +QGISDevelopmentTeam.QGISBucuresti +QGISDevelopmentTeam.QGISPi +MichaelHansen.QTextPad +HannaKnutsson.Qalculate +LarusStone.QtSpim +ModuleArt.QuickPictureViewer +PaddyXu.QuickLook +Quicken.Quicken +RCoreTeam.RforWindows +RCoreTeam.RforWindows +RCoreTeam.RforWindows +RStudio.RStudio +Rambox.Rambox +OlegDanilov.RapidEnvironmentEditor +RaspberryPi.RaspberryPiImager +rawtherapeecom.RawTherapee +PaulRawnsley.RedditWallpaperChanger +jklSoft.Rekodecompilerfor +Devolutions.RemoteDesktopManager +Devolutions.RemoteDesktopManagerFree +RemoteMouse.RemoteMouse +BaldurKarlsson.RenderDoc +Antmicro.Renode +Responsively.ResponsivelyApp +RetroShareTeam.RetroShare +VSRevoGroup.RevoUninstaller +VSRevoGroup.RevoUninstallerPro +3TSoftwareLabs.Robo3T +3TSoftwareLabs.Robo3T +3TSoftwareLabs.Robo3T +RocketChatSupport.RocketChat +PunkSoftware.RocketDock +ArtsoftEntertainment.RocksnDiamonds +MarkoBL.Rosi +code4ward.RoyalTS +RoyalApps.RoyalTS +TheRFoundation.Rtools +RubyInstallerTeam.Ruby +RubyInstallerTeam.RubywithMSYS2 +RubyInstallerTeam.Ruby +LukeHaas.RunJS +LukeHaas.RunJS +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TheRustProjectDevelopers.Rust +TopalaSoftwareSolutions.SIW2020aTrial +RicardoVillalba.SMPlayer +Navimatics.SSHFSWin2020 +DotzSoftwares.SVGExplorerExtension +SamsungElectronics.SamsungDeX +mircearoata.SatisfactoryModLauncher +ScratchFoundation.ScratchDesktop +NickeManarin.ScreenToGif +TheScribusTeam.Scribus +TheScummVMTeam.ScummVM +spikespaz.SearchDeflector +Sejda.SejdaPDFDesktop +Datalust.Seq +Microsoft.SharePointOnlineManagementShell +ShareXTeam.ShareX +RandyRantscom.SharpKeys +Meltytech.Shotcut +SigilEbook.Sigil +OpenWhisperSystems.Signal +OpenWhisperSystems.Signal +OpenWhisperSystems.Signal +OpenWhisperSystems.Signal +OpenWhisperSystems.Signal +OpenWhisperSystems.Signal +OpenWhisperSystems.Signal +Approximatrix.SimplyFortran3 +AshleyStone.SitdownMW +SkypeTechnologies.Skype +SkypeTechnologies.Skype +SkypeTechnologies.Skype +SlackTechnologies.SlackMachineWide +TechSmith.Snagit2020 +SnakeNestcom.SnakeTail +CoryPlotts.Snoop +SmartBearSoftware.SoapUI +SonicPi.SonicPi +Sonos.Sonos +Sonos.SonosController +AntoineAflalo.SoundSwitch +Atlassian.Sourcetree +SpeedCrunch.SpeedCrunch +SpekProject.Spek +StandardNotes.StandardNotes +Valve.Steam +wwwsbclorg.SteelBankCommonLisp +SteelSeries.SteelSeriesEngine +Stellariumteam.Stellarium +Stellariumteam.Stellarium +Stellariumteam.Stellarium +strawberryperlcomproject.StrawberryPerl +GeneralWorkings.StreamlabsOBS +GeneralWorkings.StreamlabsOBS +GeneralWorkings.StreamlabsOBS +Streamlink.Streamlink +SebastianMeyer.StreamlinkTwitchGUI +JanHovancik.Stretchly +JanHovancik.Stretchly +JanHovancik.Stretchly +Stride.Stride +BrickLink.Studio +SublimeHQ.SublimeMerge +SublimeHQ.SublimeText3 +KrzysztofKowalczyk.SumatraPDF +SuperColliderCommunity.SuperCollider +SuperTuxKart.SuperTuxKart3Dopensourcearcaderacerwithavarietycharacterstracksandmodestoplay +Microsoft.SurfaceDuoEmulator +SyncTrayzor.SyncTrayzor +MisterGroup.SystemExplorer +OpenVPNTechnologies.TAPWindows +erengy.Taiga +Tailscale.Tailscale +Tailscale.TailscaleIPN +TaiseiProject.TaiseiProject +Taskcade.Taskade +Taskcade.Taskade +TreasureData.Tdagent +TreasureData.Tdagent +BenitovanderZander.TeXstudioTeXstudioisafullyfeaturedLaTeXeditor +TeXUsersGroup.TeXworks +TeamSpeakSystems.TeamSpeak3Client +TechPowerUp.TechPowerUpGPUZ +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TelegramFZ.TelegramDesktop +TeraTermProject.TeraTerm +EugenePankov.Terminus +EugenePankov.Terminus +EugenePankov.Terminus +CompuPhase.Termite +TesseractOCRcommunity.TesseractOCRopensourceOCRengine +Texmaker.Texmaker +Texnomic.TexnomicSecureDNSTerminal +RaMMicHaeL.Textify +Appestcom.TickTick +GlavSoft.TightVNC +TikzEdt.TikzEdt +mapeditororg.Tiled +Nadeo.TmNationsForever +Toggl.TogglDesktop +Toggl.TogglTrack +TortoiseGit.TortoiseGit +TortoiseSVN.TortoiseSVN +TortoiseSVN.TortoiseSVN +TranslucentTBOpenSourceDevelopers.TranslucentTB +TransmissionProject.Transmission +YurySidorovTransmissionRemoteGUIworkinggroup.TransmissionRemoteGUI +BinaryFortressSoftware.TrayStatus +BinaryFortressSoftware.TrayStatus +JAMSoftware.TreeSizeFree +JAMSoftware.TreeSize +Trelbyorg.Trelby +CeruleanStudios.Trillian +TunnelBear.TunnelBear +NewBreedSoftware.TuxPaint +InspectElement.Tweeten +XanderFrangos.TwinkleTray +TwitchInteractive.Twitch +GDATACyberDefense.TypeRefHasher +SafelyRemovecom.USBSafelyRemove +DrewNaylor.UXLLauncher +DrewNaylor.UXLLauncher +Ultimaker.UltimakerCura +Ultimaker.UltimakerCura +Ultimaker.UltimakerCura +uvncbvba.UltraVnc +ReasonSoftware.Unchecky +UnifiedIntents.UnifiedRemote +UnityTechnologies.UnityHub +Microsoft.UpdateforKB2504637 +Microsoft.UpdateforMicrosoftVisualStudio2015KB3095681 +Ubisoft.Uplay +UMEZAWATakeshi.UtVideoCodecSuite +VCV.VCVRack +VideoLAN.VLCmediaplayer +VideoLAN.VLCmediaplayer +VideoLAN.VLCmediaplayer +VMware.VMwareHorizonClient +VMware.VMwarePlayer +VMware.VMwareWorkstation +RealVNC.VNCServer +RealVNC.VNCViewer +Microsoft.VSCodium +Microsoft.VSCodium +marhauserssourceforgenet.VcXsrv +BramMoolenaaretal.Vim +VirtManagerProject.VirtViewer +VivaldiTechnologies.Vivaldi +BlackTreeGaming.Vortex +VoyagerX.Vrew +LunarG.VulkanSDK +WarzoneProject.Warzone +Waterfox.WaterfoxCurrent +Waterfox.WaterfoxCurrent +Waterfox.WaterfoxCurrent +Devolutions.WaykNow +Buds.WeakAurasCompanion +Buds.WeakAurasCompanion +Buds.WeakAurasCompanion +Buds.WeakAurasCompanion +MachineLearningGroupUniversityofWaikatoHamiltonNZ.Weka +ImageWriterDevelopers.Win32DiskImager +SamHocevar.WinCompose +TimothyJohnson.WinDynamicDesktop +TimothyJohnson.WinDynamicDesktop +TimothyJohnson.WinDynamicDesktop +Navimatics.WinFsp2020 +HTTrack.WinHTTrackWebsiteCopier +ThingamahoochieSoftware.WinMerge +winrar.WinRAR +winrar.WinRAR +MartinPrikryl.WinSCP +Corel.WinZip +Winamp.Winamp +Microsoft.Windows10UpdateAssistant +Microsoft.WindowsAdminCenter +Microsoft.WindowsAssessmentandDeploymentKitWindows10 +Microsoft.WindowsAssessmentandDeploymentKitWindowsPreinstallationEnvironmentAddonsWindows10 +Microsoft.WindowsDriverKitWindows +DynastreamInnovations.WindowsDriverPackageDynastreamInnovationsANTLibUSBDrivers +SiliconLabsSoftware.WindowsDriverPackageSiliconLabsSoftwareUSB +Microsoft.WindowsSDKAddOn +Microsoft.WindowsSoftwareDevelopmentKitWindows +Microsoft.WindowsSoftwareDevelopmentKitWindows +Microsoft.WindowsSoftwareDevelopmentKitWindows +WireGuard.WireGuard +TheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark +TheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark +TheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark +TheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark +AntibodySoftware.WizFile +AntibodySoftware.WizKey +AntibodySoftware.WizMouse +AntibodySoftware.WizTree +AntibodySoftware.WizTree +Automattic.WordPresscom +Automattic.WordPresscom +Automattic.WordPresscom +Automattic.WordPresscom +RobCaelersRaymondPenners.Workrave +Writage.Writage +X2GoProject.X2GoClientforWindows +Bitnami.XAMPP +ChristianHohnstaedt.XCA +TheTBOOXOpenSourceGroup.XMakebuildutility +XMind.XMind +GougeletPierree.XnView +GougeletPierree.XnViewMP +YarnContributors.Yarn +BeijingYinxiangBijiTechnologies.YinxiangBijiv +BeijingYinxiangBijiTechnologies.YinxiangBijiv +BeijingYinxiangBijiTechnologies.YinxiangBijiv +BeijingYinxiangBijiTechnologies.YinxiangBijiv +BeijingYinxiangBijiTechnologies.YinxiangBijiv +AdlerLuiz.YouTubeMusicDesktopApp +Yubico.YubiKeyManager +Zentimocom.ZentimoPRO +ZeroTier.ZeroTierOne +HendrikErz.Zettlr +RobinStuartBogDanVatra.Zint +Zoom.Zoom +Zoom.ZoomOutlookPlugin +CorporationforDigitalScholarship.Zotero +KandraLabs.Zulip +SangomaTechnologies.Zulu +ZygorGuides.ZygorClientUninstaller +Balena.balenaEtcher +Balena.balenaEtcher +Balena.balenaEtcher +Balena.balenaEtcher +Balena.balenaEtcher +Balena.balenaEtcher +Balena.balenaEtcher +Balena.balenaEtcher +NathanielJohns.beatdrop +ClementTsang.bottom +butterflowuigithub.butterflowui +KovidGoyal.calibre +ElliottZheng.copytranslator +thedarktableproject.darktable +dnGrepCommunityContributors.dnGREP +JGraph.drawio +HardcodedSoftware.dupeGuru +eMClient.eMClient +Ebbflowio.ebbflow +fluxSoftware.flux +KurataSayuri.ffftp +wereturtle.ghostwriter +gnuplotdevelopmentteam.gnuplotpatchlevel8 +StefansTools.grepWin +DrewNaylor.guinget +DrewNaylor.guinget +DrewNaylor.guinget +eVenture.hidemeVPN +eVenture.hidemeVPN +PurpleI2P.i2pd +VantageLinguistics.iSEEKAnswerWorksEnglishRuntime +Apple.iTunes +KDE.kdenlive +KDE.kdiff3 +NextGenerationSoftware.mRemoteNG +MaximaTeam.maxima +FrankSkare.mpvnet +720kb.ndm +xiles.nexusfont +ownCloud.ownCloud +EasternGraphics.pConplannerPRO +LaurentPRendeCotret.pandocplot +ThepgAdminDevelopmentTeam.pgAdmin4 +ThepgAdminDevelopmentTeam.pgAdmin4 +ThepgAdminDevelopmentTeam.pgAdmin4 +ThepgAdminDevelopmentTeam.pgAdmin4 +TheqBittorrentproject.qBittorrent +TheqBittorrentproject.qBittorrent +TheqBittorrentproject.qBittorrent +remoteit.remoteit +remoteit.remoteit +Lightbend.sbt +ScilabEnterprises.scilab +TheSqlectronTeam.sqlectron +JanHovancik.stretchly +OliverSchwendener.ueli +OliverSchwendener.ueli +OliverSchwendener.ueli +Humanity.xmoto +Humanity.xmoto +Microsoft.微软设备健康助手 +Alipaycom.支付宝安全控件 +百度在线网络技术有限公司.百度网盘 +腾讯科技有限公司.腾讯QQ diff --git a/Tests/corpus/README.md b/Tests/corpus/README.md new file mode 100644 index 0000000..94baf4c --- /dev/null +++ b/Tests/corpus/README.md @@ -0,0 +1,6 @@ +Test vectors copied verbatim from microsoft/winget-cli +src/AppInstallerCLITests/TestData/ (MIT licence). + +Line N of InputNames.txt and InputPublishers.txt must normalise to +line N of NormalizationInitialIds.txt, formatted ".". +See NameNormalizationTests.cpp:93-95.