public static IEnumerable <ApplicationUninstallerEntry> DriveApplicationScan( ListGenerationProgress.ListGenerationCallback progressCallback, List <string> dirsToSkip, List <KeyValuePair <DirectoryInfo, bool?> > itemsToScan) { var dividedItems = SplitByPhysicalDrives(itemsToScan, pair => pair.Key); void GetUninstallerEntriesThread(KeyValuePair <DirectoryInfo, bool?> data, List <ApplicationUninstallerEntry> state) { if (UninstallToolsGlobalConfig.IsSystemDirectory(data.Key) || data.Key.Name.StartsWith("Windows", StringComparison.InvariantCultureIgnoreCase)) { return; } var detectedEntries = DirectoryFactory.TryCreateFromDirectory(data.Key, data.Value, dirsToSkip).ToList(); ApplicationUninstallerFactory.MergeResults(state, detectedEntries, null); } var workSpreader = new ThreadedWorkSpreader <KeyValuePair <DirectoryInfo, bool?>, List <ApplicationUninstallerEntry> > (MaxThreadsPerDrive, GetUninstallerEntriesThread, list => new List <ApplicationUninstallerEntry>(list.Count), data => data.Key.FullName); workSpreader.Start(dividedItems, progressCallback); var results = new List <ApplicationUninstallerEntry>(); foreach (var workerResults in workSpreader.Join()) { ApplicationUninstallerFactory.MergeResults(results, workerResults, null); } return(results); }
public static void GenerateMisingInformation(List <ApplicationUninstallerEntry> entries, InfoAdderManager infoAdder, List <Guid> msiProducts, bool skipRunLast, ListGenerationProgress.ListGenerationCallback progressCallback) { void WorkLogic(ApplicationUninstallerEntry entry, object state) { infoAdder.AddMissingInformation(entry, skipRunLast); if (msiProducts != null) { entry.IsValid = FactoryTools.CheckIsValid(entry, msiProducts); } } var workSpreader = new ThreadedWorkSpreader <ApplicationUninstallerEntry, object>(MaxThreadsPerDrive, WorkLogic, list => null, entry => entry.DisplayName ?? entry.RatingId ?? string.Empty); var cDrive = new DirectoryInfo(Environment.SystemDirectory).Root; var dividedItems = SplitByPhysicalDrives(entries, entry => { var loc = entry.InstallLocation ?? entry.UninstallerLocation; if (!string.IsNullOrEmpty(loc)) { try { return(new DirectoryInfo(loc)); } catch (SystemException ex) { Console.WriteLine(ex); } } return(cDrive); }); workSpreader.Start(dividedItems, progressCallback); workSpreader.Join(); }
public IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { var uninstallerRegistryKeys = new List <KeyValuePair <RegistryKey, bool> >(); progressCallback(new ListGenerationProgress(0, -1, Localisation.Progress_Registry_Gathering)); foreach (var kvp in GetParentRegistryKeys()) { uninstallerRegistryKeys.AddRange( kvp.Key.GetSubKeyNames() .Select(subkeyName => OpenSubKeySafe(kvp.Key, subkeyName)) .Where(subkey => subkey != null) .Select(subkey => new KeyValuePair <RegistryKey, bool>(subkey, kvp.Value))); kvp.Key.Close(); } void WorkLogic(KeyValuePair <RegistryKey, bool> data, List <ApplicationUninstallerEntry> state) { try { var entry = TryCreateFromRegistry(data.Key, data.Value); if (entry != null) { state.Add(entry); } } catch (Exception ex) { //Uninstaller is invalid or there is no uninstaller in the first place. Skip it to avoid problems. Console.WriteLine($@"Failed to extract reg entry {data.Key.Name} - {ex}"); } finally { data.Key.Close(); } } var workSpreader = new ThreadedWorkSpreader <KeyValuePair <RegistryKey, bool>, List <ApplicationUninstallerEntry> >( FactoryThreadedHelpers.MaxThreadsPerDrive, WorkLogic, list => new List <ApplicationUninstallerEntry>(list.Count), pair => { try { return(string.Format(Localisation.Progress_Registry_Processing, Path.GetFileName(pair.Key.Name))); } catch { return(string.Empty); } }); // We are mostly reading from registry, so treat everything as on a single drive var dataBuckets = new List <List <KeyValuePair <RegistryKey, bool> > > { uninstallerRegistryKeys }; workSpreader.Start(dataBuckets, progressCallback); return(workSpreader.Join().SelectMany(x => x).ToList()); }