public IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { progressCallback(new ListGenerationProgress(0, -1, Localisation.Progress_DriveScan_Gathering)); var existingUninstallers = _existingUninstallerEntries.ToList(); var pfDirs = UninstallToolsGlobalConfig.GetProgramFilesDirectories(true).ToList(); var dirsToSkip = GetDirectoriesToSkip(existingUninstallers, pfDirs).ToList(); var itemsToScan = GetDirectoriesToScan(existingUninstallers, pfDirs, dirsToSkip).ToList(); return(FactoryThreadedHelpers.DriveApplicationScan(progressCallback, dirsToSkip, itemsToScan)); }
public static IList <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback callback) { const int totalStepCount = 8; var currentStep = 1; var concurrentFactory = new ConcurrentApplicationFactory(GetMiscUninstallerEntries); try { // Find msi products --------------------------------------------------------------------------------------- var msiProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_MSI); callback(msiProgress); var msiGuidCount = 0; var msiProducts = MsiTools.MsiEnumProducts().DoForEach(x => { msiProgress.Inner = new ListGenerationProgress(0, -1, string.Format(Localisation.Progress_MSI_sub, ++msiGuidCount)); callback(msiProgress); }).ToList(); // Run some factories in a separate thread ----------------------------------------------------------------- concurrentFactory.Start(); // Find stuff mentioned in registry ------------------------------------------------------------------------ List <ApplicationUninstallerEntry> registryResults; if (UninstallToolsGlobalConfig.ScanRegistry) { var regProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Registry); callback(regProgress); var registryFactory = new RegistryFactory(msiProducts); registryResults = registryFactory.GetUninstallerEntries(report => { regProgress.Inner = report; callback(regProgress); }).ToList(); // Fill in install llocations for DirectoryFactory to improve speed and quality of results if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null) { ApplyCache(registryResults, UninstallToolsGlobalConfig.UninstallerFactoryCache, InfoAdder); } var installLocAddProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_GatherUninstallerInfo); callback(installLocAddProgress); FactoryThreadedHelpers.GenerateMisingInformation(registryResults, InfoAdder, null, true, report => { installLocAddProgress.Inner = report; callback(installLocAddProgress); }); } else { registryResults = new List <ApplicationUninstallerEntry>(); } // Look for entries on drives, based on info in registry. ---------------------------------------------------- // Will introduce duplicates to already detected stuff. Need to check for duplicates with other entries later. List <ApplicationUninstallerEntry> driveResults; if (UninstallToolsGlobalConfig.ScanDrives) { var driveProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_DriveScan); callback(driveProgress); var driveFactory = new DirectoryFactory(registryResults); driveResults = driveFactory.GetUninstallerEntries(report => { driveProgress.Inner = report; callback(driveProgress); }).ToList(); } else { driveResults = new List <ApplicationUninstallerEntry>(); } // Join up with the thread ---------------------------------------------------------------------------------- var miscProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_AppStores); callback(miscProgress); var otherResults = concurrentFactory.GetResults(callback, miscProgress); // Handle duplicate entries ---------------------------------------------------------------------------------- var mergeProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Merging); callback(mergeProgress); var mergedResults = registryResults.ToList(); MergeResults(mergedResults, otherResults, report => { mergeProgress.Inner = report; report.TotalCount *= 2; report.Message = Localisation.Progress_Merging_Stores; callback(mergeProgress); }); // Make sure to merge driveResults last MergeResults(mergedResults, driveResults, report => { mergeProgress.Inner = report; report.CurrentCount += report.TotalCount; report.TotalCount *= 2; report.Message = Localisation.Progress_Merging_Drives; callback(mergeProgress); }); // Fill in any missing information ------------------------------------------------------------------------- if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null) { ApplyCache(mergedResults, UninstallToolsGlobalConfig.UninstallerFactoryCache, InfoAdder); } var infoAddProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_GeneratingInfo); callback(infoAddProgress); FactoryThreadedHelpers.GenerateMisingInformation(mergedResults, InfoAdder, msiProducts, false, report => { infoAddProgress.Inner = report; callback(infoAddProgress); }); // Cache missing information to speed up future scans if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null) { foreach (var entry in mergedResults) { UninstallToolsGlobalConfig.UninstallerFactoryCache.TryCacheItem(entry); } try { UninstallToolsGlobalConfig.UninstallerFactoryCache.Save(); } catch (SystemException e) { Console.WriteLine(@"Failed to save cache: " + e); } } // Detect startups and attach them to uninstaller entries ---------------------------------------------------- var startupsProgress = new ListGenerationProgress(currentStep, totalStepCount, Localisation.Progress_Startup); callback(startupsProgress); var i = 0; var startupEntries = new List <StartupEntryBase>(); foreach (var factory in StartupManager.Factories) { startupsProgress.Inner = new ListGenerationProgress(i++, StartupManager.Factories.Count, factory.Key); callback(startupsProgress); try { startupEntries.AddRange(factory.Value()); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } startupsProgress.Inner = new ListGenerationProgress(1, 1, Localisation.Progress_Merging); callback(startupsProgress); try { AttachStartupEntries(mergedResults, startupEntries); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } return(mergedResults); } finally { concurrentFactory.Dispose(); } }