CmdPal: Linq clean-up (All Apps) (#41551)

Beginning the process of removing System.Linq from CmdPal. This PR
removes it from the All Apps extension.
This commit is contained in:
Michael Jolley
2025-09-26 11:15:34 -05:00
committed by GitHub
parent 7b7bae2889
commit 3bdb5305ba
17 changed files with 380 additions and 165 deletions

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using Windows.Management.Deployment;
@@ -26,9 +25,19 @@ public class PackageManagerWrapper : IPackageManager
{
var pkgs = _packageManager.FindPackagesForUser(user.Value);
return pkgs.Select(PackageWrapper.GetWrapperFromPackage).Where(package => package is not null);
ICollection<IPackage> packages = [];
foreach (var package in pkgs)
{
if (package is not null)
{
packages.Add(PackageWrapper.GetWrapperFromPackage(package));
}
}
return packages;
}
return Enumerable.Empty<IPackage>();
return [];
}
}

View File

@@ -6,7 +6,6 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using ManagedCommon;
@@ -72,18 +71,20 @@ public partial class UWP
PInvoke.SHCreateStreamOnFileEx(path, STGMREAD, noAttribute, false, null, &stream).ThrowOnFailure();
using var streamHandle = new SafeComHandle((IntPtr)stream);
Apps = AppxPackageHelper.GetAppsFromManifest(stream).Select(appInManifest =>
var appsInManifest = AppxPackageHelper.GetAppsFromManifest(stream);
foreach (var appInManifest in appsInManifest)
{
using var appHandle = new SafeComHandle(appInManifest);
return new UWPApplication((IAppxManifestApplication*)appInManifest, this);
}).Where(a =>
{
var valid =
!string.IsNullOrEmpty(a.UserModelId) &&
!string.IsNullOrEmpty(a.DisplayName) &&
a.AppListEntry != "none";
return valid;
}).ToList();
var uwpApp = new UWPApplication((IAppxManifestApplication*)appInManifest, this);
if (!string.IsNullOrEmpty(uwpApp.UserModelId) &&
!string.IsNullOrEmpty(uwpApp.DisplayName) &&
uwpApp.AppListEntry != "none")
{
Apps.Add(uwpApp);
}
}
}
catch (Exception ex)
{
@@ -93,19 +94,31 @@ public partial class UWP
}
}
// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx
private static string[] XmlNamespaces(string path)
{
var z = XDocument.Load(path);
if (z.Root is not null)
{
var namespaces = z.Root.Attributes().
Where(a => a.IsNamespaceDeclaration).
GroupBy(
a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName,
a => XNamespace.Get(a.Value)).Select(
g => g.First().ToString()).ToArray();
return namespaces;
var namespaces = new HashSet<string>();
var attributes = z.Root.Attributes();
foreach (var attribute in attributes)
{
if (attribute.IsNamespaceDeclaration)
{
// Extract namespace
var key = attribute.Name.Namespace == XNamespace.None ? string.Empty : attribute.Name.LocalName;
XNamespace ns = XNamespace.Get(attribute.Value);
var nsString = ns.ToString();
// Use HashSet to check for duplicates
namespaces.Add(nsString);
}
}
var uniqueNamespaces = new string[namespaces.Count];
namespaces.CopyTo(uniqueNamespaces);
return uniqueNamespaces;
}
else
{
@@ -115,10 +128,13 @@ public partial class UWP
private void InitPackageVersion(string[] namespaces)
{
foreach (var n in _versionFromNamespace.Keys.Where(namespaces.Contains))
foreach (var n in _versionFromNamespace.Keys)
{
Version = _versionFromNamespace[n];
return;
if (Array.IndexOf(namespaces, n) >= 0)
{
Version = _versionFromNamespace[n];
return;
}
}
Version = PackageVersion.Unknown;
@@ -137,7 +153,18 @@ public partial class UWP
foreach (var app in u.Apps)
{
if (AllAppsSettings.Instance.DisabledProgramSources.All(x => x.UniqueIdentifier != app.UniqueIdentifier))
var isDisabled = false;
foreach (var disabled in AllAppsSettings.Instance.DisabledProgramSources)
{
if (disabled.UniqueIdentifier == app.UniqueIdentifier)
{
isDisabled = true;
break;
}
}
if (!isDisabled)
{
appsBag.Add(app);
}
@@ -154,20 +181,28 @@ public partial class UWP
private static IEnumerable<IPackage> CurrentUserPackages()
{
return PackageManagerWrapper.FindPackagesForCurrentUser().Where(p =>
var currentUsersPackages = PackageManagerWrapper.FindPackagesForCurrentUser();
ICollection<IPackage> packagesToReturn = [];
foreach (var pkg in currentUsersPackages)
{
try
{
var f = p.IsFramework;
var path = p.InstalledLocation;
return !f && !string.IsNullOrEmpty(path);
var f = pkg.IsFramework;
var path = pkg.InstalledLocation;
if (!f && !string.IsNullOrEmpty(path))
{
packagesToReturn.Add(pkg);
}
}
catch (Exception ex)
{
Logger.LogError(ex.Message);
return false;
}
});
}
return packagesToReturn;
}
public override string ToString()

View File

@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Xml;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Commands;
@@ -348,20 +347,22 @@ public class UWPApplication : IUWPApplication
//
// FirstOrDefault would result in us using the 1x scaled icon
// always, which is usually too small for our needs.
var selectedIconPath = paths.LastOrDefault(File.Exists);
if (!string.IsNullOrEmpty(selectedIconPath))
for (var i = paths.Count - 1; i >= 0; i--)
{
LogoPath = selectedIconPath;
if (highContrast)
if (File.Exists(paths[i]))
{
LogoType = LogoType.HighContrast;
}
else
{
LogoType = LogoType.Colored;
}
LogoPath = paths[i];
if (highContrast)
{
LogoType = LogoType.HighContrast;
}
else
{
LogoType = LogoType.Colored;
}
return true;
return true;
}
}
}
@@ -402,7 +403,23 @@ public class UWPApplication : IUWPApplication
}
}
var selectedIconPath = paths.OrderBy(x => Math.Abs(pathFactorPairs.GetValueOrDefault(x) - appIconSize)).FirstOrDefault(File.Exists);
// Sort paths by distance to desired app icon size
var selectedIconPath = string.Empty;
var closestDistance = int.MaxValue;
foreach (var p in paths)
{
if (File.Exists(p) && pathFactorPairs.TryGetValue(p, out var factor))
{
var distance = Math.Abs(factor - appIconSize);
if (distance < closestDistance)
{
closestDistance = distance;
selectedIconPath = p;
}
}
}
if (!string.IsNullOrEmpty(selectedIconPath))
{
LogoPath = selectedIconPath;

View File

@@ -7,7 +7,6 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using System.Security;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -616,9 +615,24 @@ public class Win32Program : IProgram
}
private static IEnumerable<string> CustomProgramPaths(IEnumerable<ProgramSource> sources, IList<string> suffixes)
=> sources?.Where(programSource => Directory.Exists(programSource.Location) && programSource.Enabled)
.SelectMany(programSource => ProgramPaths(programSource.Location, suffixes))
.ToList() ?? Enumerable.Empty<string>();
{
if (sources is not null)
{
var paths = new List<string>();
foreach (var programSource in sources)
{
if (Directory.Exists(programSource.Location) && programSource.Enabled)
{
paths.AddRange(ProgramPaths(programSource.Location, suffixes));
}
}
return paths;
}
return [];
}
// Function to obtain the list of applications, the locations of which have been added to the env variable PATH
private static List<string> PathEnvironmentProgramPaths(IList<string> suffixes)
@@ -647,9 +661,15 @@ public class Win32Program : IProgram
}
private static List<string> IndexPath(IList<string> suffixes, List<string> indexLocations)
=> indexLocations
.SelectMany(indexLocation => ProgramPaths(indexLocation, suffixes))
.ToList();
{
var paths = new List<string>();
foreach (var indexLocation in indexLocations)
{
paths.AddRange(ProgramPaths(indexLocation, suffixes));
}
return paths;
}
private static List<string> StartMenuProgramPaths(IList<string> suffixes)
{
@@ -691,17 +711,51 @@ public class Win32Program : IProgram
}
}
return paths
.Where(path => suffixes.Any(suffix => path.EndsWith(suffix, StringComparison.InvariantCultureIgnoreCase)))
.Select(ExpandEnvironmentVariables)
.Where(path => path is not null)
.ToList();
var returnedPaths = new List<string>();
foreach (var path in paths)
{
var matchesSuffix = false;
foreach (var suffix in suffixes)
{
if (path.EndsWith(suffix, StringComparison.InvariantCultureIgnoreCase))
{
matchesSuffix = true;
break;
}
}
if (matchesSuffix)
{
var expandedPath = ExpandEnvironmentVariables(path);
if (expandedPath is not null)
{
returnedPaths.Add(expandedPath);
}
}
}
return returnedPaths;
}
private static IEnumerable<string> GetPathsFromRegistry(RegistryKey root)
=> root
.GetSubKeyNames()
.Select(x => GetPathFromRegistrySubkey(root, x));
{
var result = new List<string>();
// Get all subkey names
var subKeyNames = root.GetSubKeyNames();
// Process each subkey to extract the path
foreach (var subkeyName in subKeyNames)
{
var path = GetPathFromRegistrySubkey(root, subkeyName);
if (!string.IsNullOrEmpty(path))
{
result.Add(path);
}
}
return result;
}
private static string GetPathFromRegistrySubkey(RegistryKey root, string subkey)
{
@@ -765,7 +819,28 @@ public class Win32Program : IProgram
}
public static List<Win32Program> DeduplicatePrograms(IEnumerable<Win32Program> programs)
=> new HashSet<Win32Program>(programs, Win32ProgramEqualityComparer.Default).ToList();
{
// Create a HashSet with the custom equality comparer to automatically deduplicate programs
var uniquePrograms = new HashSet<Win32Program>(Win32ProgramEqualityComparer.Default);
// Filter out invalid programs and add valid ones to the HashSet
foreach (var program in programs)
{
if (program?.Valid == true)
{
uniquePrograms.Add(program);
}
}
// Convert the HashSet to a List for return
var result = new List<Win32Program>(uniquePrograms.Count);
foreach (var program in uniquePrograms)
{
result.Add(program);
}
return result;
}
private static Win32Program GetProgramFromPath(string path)
{
@@ -881,8 +956,22 @@ public class Win32Program : IProgram
foreach (var path in source.GetPaths())
{
if (disabledProgramsList.All(x => x.UniqueIdentifier != path) &&
!ExecutableApplicationExtensions.Contains(Extension(path)))
if (ExecutableApplicationExtensions.Contains(Extension(path)))
{
continue;
}
var isDisabled = false;
foreach (var disabledProgram in disabledProgramsList)
{
if (disabledProgram.UniqueIdentifier == path)
{
isDisabled = true;
break;
}
}
if (!isDisabled)
{
pathBag.Add(path);
}
@@ -902,7 +991,17 @@ public class Win32Program : IProgram
foreach (var path in source.GetPaths())
{
if (disabledProgramsList.All(x => x.UniqueIdentifier != path))
var isDisabled = false;
foreach (var disabledProgram in disabledProgramsList)
{
if (disabledProgram.UniqueIdentifier == path)
{
isDisabled = true;
break;
}
}
if (!isDisabled)
{
runCommandPathBag.Add(path);
}
@@ -931,10 +1030,8 @@ public class Win32Program : IProgram
}
});
var programs = programsList.ToList();
var runCommandPrograms = runCommandProgramsList.ToList();
return DeduplicatePrograms(programs.Concat(runCommandPrograms).Where(program => program?.Valid == true));
List<Win32Program> allPrograms = [.. programsList, .. runCommandProgramsList];
return DeduplicatePrograms(allPrograms);
}
catch (Exception e)
{