using Microsoft.Win32; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace WelsonJS.Launcher.Tools { public class ExecutablesCollector { private List<string> executables = new List<string>(); public ExecutablesCollector() { new Task(() => { executables.AddRange(GetInstalledSoftwareExecutables()); executables.AddRange(GetExecutablesFromPath()); executables.AddRange(GetExecutablesFromNetFx()); }).Start(); } public List<string> GetExecutables() { return executables; } private List<string> GetInstalledSoftwareExecutables() { List<string> executables = new List<string>(); string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey)) { if (key != null) { foreach (string subKeyName in key.GetSubKeyNames()) { using (RegistryKey subKey = key.OpenSubKey(subKeyName)) { string installLocation = subKey?.GetValue("InstallLocation") as string; string uninstallString = subKey?.GetValue("UninstallString") as string; List<string> executablePaths = FindExecutables(installLocation, uninstallString); executables.AddRange(executablePaths); } } } } return executables; } private List<string> FindExecutables(string installLocation, string uninstallString) { List<string> executables = new List<string>(); if (!string.IsNullOrEmpty(installLocation) && Directory.Exists(installLocation)) { try { List<string> executableFiles = Directory.GetFiles(installLocation, "*.exe", SearchOption.AllDirectories) .OrderByDescending(f => new FileInfo(f).Length) .ToList(); executables.AddRange(executableFiles); } catch (Exception ex) { Debug.WriteLine($"Error enumerating executables in '{installLocation}': {ex}"); } } if (!string.IsNullOrEmpty(uninstallString)) { if (TryParseExecutablePath(uninstallString, out string executablePath)) { executables.Add(executablePath); } } return executables; } private static bool TryParseExecutablePath(string s, out string path) { Match match = Regex.Match(s, @"(?<=""|^)([a-zA-Z]:\\[^""]+\.exe)", RegexOptions.IgnoreCase); if (match.Success) { path = match.Value; return true; } path = null; return false; } private List<string> GetExecutablesFromPath() { List<string> executables = new List<string>(); string[] paths = Environment.GetEnvironmentVariable("PATH")?.Split(';'); if (paths != null) { foreach (string path in paths) { if (Directory.Exists(path)) { try { executables.AddRange(Directory.GetFiles(path, "*.exe", SearchOption.TopDirectoryOnly)); } catch (Exception ex) { Debug.WriteLine($"Error enumerating executables in '{path}': {ex}"); } } } } return executables; } private List<string> GetExecutablesFromNetFx() { List<string> executables = new List<string>(); string windir = Environment.GetEnvironmentVariable("WINDIR"); if (!string.IsNullOrEmpty(windir)) { string[] paths = new string[] { Path.Combine(windir, "Microsoft.NET", "Framework"), Path.Combine(windir, "Microsoft.NET", "Framework64") }; foreach (string path in paths) { if (Directory.Exists(path)) { try { executables.AddRange(Directory.GetFiles(path, "*.exe", SearchOption.AllDirectories)); } catch (Exception ex) { Debug.WriteLine($"Error enumerating executables in '{path}': {ex}"); } } } } return executables; } } }