diff --git a/src/Winhance.Core/Features/SoftwareApps/Models/ExternalAppDefinitions.RuntimesAndDependencies.cs b/src/Winhance.Core/Features/SoftwareApps/Models/ExternalAppDefinitions.RuntimesAndDependencies.cs index f0e48f052..7d0157a2e 100644 --- a/src/Winhance.Core/Features/SoftwareApps/Models/ExternalAppDefinitions.RuntimesAndDependencies.cs +++ b/src/Winhance.Core/Features/SoftwareApps/Models/ExternalAppDefinitions.RuntimesAndDependencies.cs @@ -20,7 +20,7 @@ public static ItemGroup GetRuntimesAndDependencies() Id = "external-app-dotnet-runtime-3-1", Name = "Microsoft .NET Runtime 3.1", Description = ".NET Runtime 3.1 for running applications", - RegistryDisplayName = "Microsoft .NET Runtime - 3.1.{version} ({arch})", + RegistryDisplayName = "Microsoft .NET Runtime - 3.1.{version} ({arch})|Microsoft .NET Core Runtime - 3.1.{version} ({arch})", GroupName = "Runtimes & Dependencies", WinGetPackageId = ["Microsoft.DotNet.Runtime.3_1"], ChocoPackageId = "dotnetcore-3.1-runtime", @@ -218,7 +218,7 @@ public static ItemGroup GetRuntimesAndDependencies() Id = "external-app-vcredist-2015-2022-x86", Name = "Visual C++ 2015-2022 (x86)", Description = "Visual C++ 2015-2022 runtime components", - RegistryDisplayName = "Microsoft Visual C++ 2015-2022 Redistributable (x86) - {version}", + RegistryDisplayName = "Microsoft Visual C++ 2015-2022 Redistributable (x86) - {version}|Microsoft Visual C++ v14 Redistributable (x86) - {version}", GroupName = "Runtimes & Dependencies", WinGetPackageId = ["Microsoft.VCRedist.2015+.x86"], ChocoPackageId = "vcredist140", @@ -229,7 +229,7 @@ public static ItemGroup GetRuntimesAndDependencies() Id = "external-app-vcredist-2015-2022-x64", Name = "Visual C++ 2015-2022 (x64)", Description = "Visual C++ 2015-2022 runtime components", - RegistryDisplayName = "Microsoft Visual C++ 2015-2022 Redistributable (x64) - {version}", + RegistryDisplayName = "Microsoft Visual C++ 2015-2022 Redistributable (x64) - {version}|Microsoft Visual C++ v14 Redistributable (x64) - {version}", GroupName = "Runtimes & Dependencies", WinGetPackageId = ["Microsoft.VCRedist.2015+.x64"], ChocoPackageId = "vcredist140", @@ -240,7 +240,7 @@ public static ItemGroup GetRuntimesAndDependencies() Id = "external-app-vcredist-2022-arm64", Name = "Visual C++ 2022 (ARM64)", Description = "Visual C++ 2022 runtime components for ARM64", - RegistryDisplayName = "Microsoft Visual C++ 2022 Redistributable (arm64) - {version}", + RegistryDisplayName = "Microsoft Visual C++ 2022 Redistributable (arm64) - {version}|Microsoft Visual C++ v14 Redistributable (arm64) - {version}", GroupName = "Runtimes & Dependencies", WinGetPackageId = ["Microsoft.VCRedist.2015+.arm64"], ChocoPackageId = "vcredist140", diff --git a/src/Winhance.Infrastructure/Features/SoftwareApps/Services/AppStatusDiscoveryService.cs b/src/Winhance.Infrastructure/Features/SoftwareApps/Services/AppStatusDiscoveryService.cs index 50b8e43b5..400d893ab 100644 --- a/src/Winhance.Infrastructure/Features/SoftwareApps/Services/AppStatusDiscoveryService.cs +++ b/src/Winhance.Infrastructure/Features/SoftwareApps/Services/AppStatusDiscoveryService.cs @@ -297,11 +297,15 @@ internal static bool MatchesPattern(string input, string pattern) if (string.IsNullOrEmpty(input)) return false; - var regexPattern = Regex.Escape(pattern) - .Replace(@"\{version}", ".+?") - .Replace(@"\{arch}", ".+?") - .Replace(@"\{locale}", ".+?"); - return Regex.IsMatch(input, $"^{regexPattern}$", RegexOptions.IgnoreCase); + var patterns = pattern.Split('|'); + return patterns.Any(p => + { + var regexPattern = Regex.Escape(p) + .Replace(@"\{version}", ".+?") + .Replace(@"\{arch}", ".+?") + .Replace(@"\{locale}", ".+?"); + return Regex.IsMatch(input, $"^{regexPattern}$", RegexOptions.IgnoreCase); + }); } #region External Apps Detection diff --git a/tests/Winhance.Infrastructure.Tests/Services/AppStatusDiscoveryServiceTests.cs b/tests/Winhance.Infrastructure.Tests/Services/AppStatusDiscoveryServiceTests.cs index f24e07233..300468a60 100644 --- a/tests/Winhance.Infrastructure.Tests/Services/AppStatusDiscoveryServiceTests.cs +++ b/tests/Winhance.Infrastructure.Tests/Services/AppStatusDiscoveryServiceTests.cs @@ -390,12 +390,16 @@ public async Task GetExternalAppsInstallationStatusAsync_UsesWinGetCache_OnSecon [InlineData("Microsoft EdgeWebView2 Runtime", "Microsoft EdgeWebView{version}", true)] [InlineData("Trillian Machine-Wide Installer", "Trillian Machine-Wide Installer", true)] [InlineData("Microsoft Visual C++ 2008 Redistributable - x64 9.0.30729.6161", "Microsoft Visual C++ 2008 Redistributable - x64 {version}", true)] - [InlineData("Microsoft .NET Runtime - 3.1.32 (x64)", "Microsoft .NET Runtime - 3.1.{version} ({arch})", true)] + [InlineData("Microsoft .NET Core Runtime - 3.1.32 (x64)", "Microsoft .NET Runtime - 3.1.{version} ({arch})|Microsoft .NET Core Runtime - 3.1.{version} ({arch})", true)] + [InlineData("Microsoft .NET Runtime - 3.1.32 (x64)", "Microsoft .NET Runtime - 3.1.{version} ({arch})|Microsoft .NET Core Runtime - 3.1.{version} ({arch})", true)] + [InlineData("Microsoft Visual C++ v14 Redistributable (x64) - 14.51.36247", "Microsoft Visual C++ 2015-2022 Redistributable (x64) - {version}|Microsoft Visual C++ v14 Redistributable (x64) - {version}", true)] + [InlineData("Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.38.33135", "Microsoft Visual C++ 2015-2022 Redistributable (x64) - {version}|Microsoft Visual C++ v14 Redistributable (x64) - {version}", true)] [InlineData("VLC media player", "VLC media player", true)] // Negative cases [InlineData("MediaMonkey 5", "VLC media player", false)] [InlineData("GIMP 3.0.8-2", "Audacity {version}", false)] - [InlineData("Microsoft .NET Runtime - 5.0.17 (x64)", "Microsoft .NET Runtime - 3.1.{version} ({arch})", false)] + [InlineData("Microsoft .NET Runtime - 5.0.17 (x64)", "Microsoft .NET Runtime - 3.1.{version} ({arch})|Microsoft .NET Core Runtime - 3.1.{version} ({arch})", false)] + [InlineData("Microsoft Visual C++ 2013 Redistributable (x64) - 12.0.30501", "Microsoft Visual C++ 2015-2022 Redistributable (x64) - {version}|Microsoft Visual C++ v14 Redistributable (x64) - {version}", false)] [InlineData("", "Foo {version}", false)] public void MatchesPattern_ReturnsExpected(string input, string pattern, bool expected) {