Example #1
0
        private static List <ApplicationUninstallerEntry> GetMiscUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var otherResults = new List <ApplicationUninstallerEntry>();

            var miscFactories = ReflectionTools.GetTypesImplementingBase <IIndependantUninstallerFactory>()
                                .Attempt(Activator.CreateInstance)
                                .Cast <IIndependantUninstallerFactory>()
                                .Where(x => x.IsEnabled())
                                .ToList();

            var progress = 0;

            foreach (var kvp in miscFactories)
            {
                progressCallback(new ListGenerationProgress(progress++, miscFactories.Count, kvp.DisplayName));
                try
                {
                    otherResults = MergeResults(otherResults, kvp.GetUninstallerEntries(null).ToList(), null);
                }
                catch (Exception ex)
                {
                    PremadeDialogs.GenericError(ex);
                }
            }

            return(otherResults);
        }
Example #2
0
        private static List <ApplicationUninstallerEntry> GetMiscUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var otherResults = new List <ApplicationUninstallerEntry>();

            var miscFactories = ReflectionTools.GetTypesImplementingBase <IIndependantUninstallerFactory>()
                                .Attempt(Activator.CreateInstance)
                                .Cast <IIndependantUninstallerFactory>()
                                .Where(x => x.IsEnabled())
                                .ToList();

            var progress = 0;

            foreach (var kvp in miscFactories)
            {
                progressCallback(new ListGenerationProgress(progress++, miscFactories.Count, kvp.DisplayName));
                try
                {
                    var sw = Stopwatch.StartNew();
                    MergeResults(otherResults, kvp.GetUninstallerEntries(null), null);
                    Console.WriteLine($"[Performance] Factory {kvp.DisplayName} took {sw.ElapsedMilliseconds}ms to finish");
                }
                catch (Exception ex)
                {
                    PremadeDialogs.GenericError(ex);
                }
            }

            return(otherResults);
        }
Example #3
0
        public IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(
            ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            if (ScriptHelperPath == null)
            {
                yield break;
            }

            var result = FactoryTools.StartHelperAndReadOutput(ScriptHelperPath, string.Empty);

            if (string.IsNullOrEmpty(result))
            {
                yield break;
            }

            var dataSets = FactoryTools.ExtractAppDataSetsFromHelperOutput(result);

            foreach (var dataSet in dataSets)
            {
                var entry = new ApplicationUninstallerEntry();

                // Automatically fill in any supplied static properties
                foreach (var entryProp in EntryProps)
                {
                    if (!dataSet.TryGetValue(entryProp.Name, out var item) || string.IsNullOrEmpty(item))
                    {
                        continue;
                    }

                    try
                    {
                        entryProp.SetValue(entry, item, null);
                    }
                    catch (SystemException ex)
                    {
                        Console.WriteLine(ex);
                    }
                }

                if (!entry.UninstallPossible && !entry.QuietUninstallPossible)
                {
                    continue;
                }

                if (string.IsNullOrEmpty(entry.Publisher))
                {
                    entry.Publisher = "Script";
                }

                if (dataSet.TryGetValue("SystemIcon", out var icon) && !string.IsNullOrEmpty(icon))
                {
                    var iconObj = SystemIconProps
                                  .FirstOrDefault(p => p.Name.Equals(icon, StringComparison.OrdinalIgnoreCase))
                                  ?.GetValue(null, null) as Icon;
                    entry.IconBitmap = iconObj;
                }

                yield return(entry);
            }
        }
Example #4
0
        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 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();

            var progress = 0;
            var results  = new List <ApplicationUninstallerEntry>();

            foreach (var directory in itemsToScan)
            {
                progressCallback(new ListGenerationProgress(progress++, itemsToScan.Count, directory.Key.FullName));

                if (UninstallToolsGlobalConfig.IsSystemDirectory(directory.Key) ||
                    directory.Key.Name.StartsWith("Windows", StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                var detectedEntries = TryCreateFromDirectory(directory.Key, directory.Value, dirsToSkip).ToList();

                results = ApplicationUninstallerFactory.MergeResults(results, detectedEntries, null);
            }

            return(results);
        }
Example #6
0
        public IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            if (!HelperAvailable)
            {
                yield break;
            }

            var output = FactoryTools.StartProcessAndReadOutput(HelperPath, "/query");

            if (string.IsNullOrEmpty(output))
            {
                yield break;
            }

            foreach (var data in FactoryTools.ExtractAppDataSetsFromHelperOutput(output))
            {
                if (!data.ContainsKey("CanonicalName"))
                {
                    continue;
                }
                var name = data["CanonicalName"];
                if (string.IsNullOrEmpty(name))
                {
                    continue;
                }

                var uninstallStr = $"\"{HelperPath}\" /uninstall {name}";

                var entry = new ApplicationUninstallerEntry
                {
                    RatingId = name,
                    //RegistryKeyName = name,
                    UninstallString      = uninstallStr,
                    QuietUninstallString = uninstallStr,
                    IsValid         = true,
                    UninstallerKind = UninstallerType.Oculus,
                    InstallLocation = data["InstallLocation"],
                    InstallDate     = Directory.GetCreationTime(data["InstallLocation"]),
                    DisplayVersion  = data["Version"],
                    IsProtected     = "true".Equals(data["IsCore"], StringComparison.OrdinalIgnoreCase),
                };

                var executable = data["LaunchFile"];
                if (File.Exists(executable))
                {
                    ExecutableAttributeExtractor.FillInformationFromFileAttribs(entry, executable, true);
                }

                if (string.IsNullOrEmpty(entry.RawDisplayName))
                {
                    entry.RawDisplayName = name.Replace('-', ' ').ToTitleCase();
                }

                yield return(entry);
            }
        }
        private static List <ApplicationUninstallerEntry> GetMiscUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var otherResults = new List <ApplicationUninstallerEntry>();

            var miscFactories = new Dictionary <IUninstallerFactory, string>();

            if (UninstallToolsGlobalConfig.ScanPreDefined)
            {
                miscFactories.Add(new PredefinedFactory(), Localisation.Progress_AppStores_Templates);
            }
            if (UninstallToolsGlobalConfig.ScanSteam)
            {
                miscFactories.Add(new SteamFactory(), Localisation.Progress_AppStores_Steam);
            }
            if (UninstallToolsGlobalConfig.ScanStoreApps)
            {
                miscFactories.Add(new StoreAppFactory(), Localisation.Progress_AppStores_WinStore);
            }
            if (UninstallToolsGlobalConfig.ScanWinFeatures)
            {
                miscFactories.Add(new WindowsFeatureFactory(), Localisation.Progress_AppStores_WinFeatures);
            }
            if (UninstallToolsGlobalConfig.ScanWinUpdates)
            {
                miscFactories.Add(new WindowsUpdateFactory(), Localisation.Progress_AppStores_WinUpdates);
            }
            if (UninstallToolsGlobalConfig.ScanChocolatey)
            {
                miscFactories.Add(new ChocolateyFactory(), Localisation.Progress_AppStores_Chocolatey);
            }
            if (UninstallToolsGlobalConfig.ScanOculus)
            {
                miscFactories.Add(new OculusFactory(), Localisation.Progress_AppStores_Oculus);
            }

            var progress = 0;

            foreach (var kvp in miscFactories)
            {
                progressCallback(new ListGenerationProgress(progress++, miscFactories.Count, kvp.Value));
                try
                {
                    otherResults = MergeResults(otherResults, kvp.Key.GetUninstallerEntries(null).ToList(), null);
                }
                catch (Exception ex)
                {
                    PremadeDialogs.GenericError(ex);
                }
            }

            return(otherResults);
        }
Example #8
0
        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 IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(
            ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var items = new List <ApplicationUninstallerEntry>();

            var s = GetSteamUninstallerEntry();

            if (s != null)
            {
                items.Add(s);
            }

            return(items);
        }
Example #10
0
        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();
            }

            var applicationUninstallers = new List <ApplicationUninstallerEntry>();

            var progress = 0;

            foreach (var regKey in uninstallerRegistryKeys)
            {
                string name;
                try { name = Path.GetFileName(regKey.Key.Name); }
                catch { name = string.Empty; }
                progressCallback(new ListGenerationProgress(progress++, uninstallerRegistryKeys.Count, string.Format(Localisation.Progress_Registry_Processing, name)));

                try
                {
                    var entry = TryCreateFromRegistry(regKey.Key, regKey.Value);
                    if (entry != null)
                    {
                        applicationUninstallers.Add(entry);
                    }
                }
                catch (Exception ex)
                {
                    //Uninstaller is invalid or there is no uninstaller in the first place. Skip it to avoid problems.
                    Debug.Fail("Failed to extract reg entry", ex.Message);
                }
                finally
                {
                    regKey.Key.Close();
                }
            }

            return(applicationUninstallers);
        }
Example #11
0
        public void Start(IList <IList <TData> > dataBuckets, ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            if (dataBuckets == null)
            {
                throw new ArgumentNullException(nameof(dataBuckets));
            }
            if (progressCallback == null)
            {
                throw new ArgumentNullException(nameof(progressCallback));
            }

            var totalCount = dataBuckets.Aggregate(0, (i, list) => i + list.Count);

            var progress = 0;

            void OnItemDone(string itemName)
            {
                progressCallback(new ListGenerationProgress(progress++, totalCount, itemName));
            }

            foreach (var itemBucket in dataBuckets)
            {
                if (itemBucket.Count == 0)
                {
                    continue;
                }

                var threadCount = Math.Min(MaxThreadsPerBucket, itemBucket.Count / 10 + 1);

                var threadWorkItemCount = itemBucket.Count / threadCount + 1;

                for (var i = 0; i < threadCount; i++)
                {
                    var firstUnique = i * threadWorkItemCount;
                    var workerItems = itemBucket.Skip(firstUnique).Take(threadWorkItemCount).ToList();

                    var worker = new Thread(WorkerThread)
                    {
                        Name         = nameof(ThreadedWorkSpreader <TData, TState>) + "_worker",
                        IsBackground = false
                    };
                    var workerData = new WorkerData(workerItems, worker, OnItemDone, StateGenerator(itemBucket));
                    _workers.Add(workerData);
                    worker.Start(workerData);
                }
            }
        }
Example #12
0
        public IList <ApplicationUninstallerEntry> GetUninstallerEntries(
            ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var results = new List <ApplicationUninstallerEntry>();

            if (Environment.OSVersion.Version < WindowsTools.Windows7)
            {
                return(results);
            }

            Exception error = null;
            var       t     = new Thread(() =>
            {
                try
                {
                    results.AddRange(WmiQueries.GetWindowsFeatures()
                                     .Where(x => x.Enabled)
                                     .Select(WindowsFeatureToUninstallerEntry));
                }
                catch (Exception ex)
                {
                    error = ex;
                }
            });

            t.Start();

            t.Join(TimeSpan.FromSeconds(40));

            if (error != null)
            {
                throw new IOException("Error while collecting Windows Features. If Windows Update is running wait until it finishes and try again. If the error persists try restarting your computer. In case nothing helps, read the KB957310 article.", error);
            }
            if (t.IsAlive)
            {
                t.Abort();
                throw new TimeoutException("WMI query has hung while collecting Windows Features, try restarting your computer. If the error persists read the KB957310 article.");
            }

            return(results);
        }
        public IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(
            ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            if (Environment.OSVersion.Version < WindowsTools.Windows7)
            {
                return(Enumerable.Empty <ApplicationUninstallerEntry>());
            }

            Exception error = null;
            var       applicationUninstallers = new List <ApplicationUninstallerEntry>();
            var       t = new Thread(() =>
            {
                try
                {
                    applicationUninstallers.AddRange(WmiQueries.GetWindowsFeatures()
                                                     .Where(x => x.Enabled)
                                                     .Select(WindowsFeatureToUninstallerEntry));
                }
                catch (Exception ex)
                {
                    error = ex;
                }
            });

            t.Start();

            t.Join(TimeSpan.FromSeconds(40));

            if (error != null)
            {
                throw new IOException("Error while collecting Windows Features, try restarting your computer. If the error persists read the KB957310 article.", error);
            }
            if (t.IsAlive)
            {
                t.Abort();
                throw new TimeoutException("WMI query has hung while collecting Windows Features, try restarting your computer. If the error persists read the KB957310 article.");
            }

            return(applicationUninstallers);
        }
        public List <ApplicationUninstallerEntry> GetResults(ListGenerationProgress.ListGenerationCallback callback,
                                                             ListGenerationProgress parentProgress)
        {
            if (parentProgress == null)
            {
                throw new ArgumentNullException(nameof(parentProgress));
            }
            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }
            Debug.Assert(_thread != null);

            if (_thread.IsAlive)
            {
                lock (_thread)
                {
                    _parentProgress = parentProgress;

                    if (_threadLastReport != null)
                    {
                        _parentProgress.Inner = _threadLastReport;
                        callback.Invoke(_parentProgress);
                    }

                    _callback = callback;
                }

                _thread.Join();
            }

            if (_cancelled)
            {
                throw new OperationCanceledException();
            }

            return(_threadResults ?? new List <ApplicationUninstallerEntry>());
        }
Example #15
0
        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)
 {
     return(GetUpdates());
 }
Example #17
0
        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());
        }
        internal static List <ApplicationUninstallerEntry> MergeResults(ICollection <ApplicationUninstallerEntry> baseEntries,
                                                                        ICollection <ApplicationUninstallerEntry> newResults, ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            // Add all of the base results straight away
            var results  = new List <ApplicationUninstallerEntry>(baseEntries);
            var progress = 0;

            foreach (var entry in newResults)
            {
                progressCallback?.Invoke(new ListGenerationProgress(progress++, newResults.Count, null));

                var matchedEntry = baseEntries.Select(x => new { x, score = ApplicationEntryTools.AreEntriesRelated(x, entry) })
                                   .Where(x => x.score >= 1)
                                   .OrderByDescending(x => x.score)
                                   .Select(x => x.x)
                                   .FirstOrDefault();

                if (matchedEntry != null)
                {
                    // Prevent setting incorrect UninstallerType
                    if (matchedEntry.UninstallPossible)
                    {
                        entry.UninstallerKind = UninstallerType.Unknown;
                    }

                    InfoAdder.CopyMissingInformation(matchedEntry, entry);
                    continue;
                }

                // If the entry failed to match to anything, add it to the results
                results.Add(entry);
            }

            return(results);
        }
        public static IList <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback callback)
        {
            const int totalStepCount = 8;
            var       currentStep    = 1;

            // 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();

            // 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 instal llocations for the drive search
                if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null)
                {
                    ApplyCache(registryResults, UninstallToolsGlobalConfig.UninstallerFactoryCache, InfoAdder);
                }

                var installLocAddProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_GatherUninstallerInfo);
                callback(installLocAddProgress);
                var installLocAddCount = 0;
                foreach (var result in registryResults)
                {
                    installLocAddProgress.Inner = new ListGenerationProgress(installLocAddCount++, registryResults.Count, result.DisplayName ?? string.Empty);
                    callback(installLocAddProgress);

                    InfoAdder.AddMissingInformation(result, true);
                }
            }
            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>();
            }

            // Get misc entries that use fancy logic --------------------------------------------------------------------
            var miscProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_AppStores);

            callback(miscProgress);
            var otherResults = GetMiscUninstallerEntries(report =>
            {
                miscProgress.Inner = report;
                callback(miscProgress);
            });

            // Handle duplicate entries ----------------------------------------------------------------------------------
            var mergeProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Merging);

            callback(mergeProgress);
            var mergedResults = registryResults.ToList();

            mergedResults = MergeResults(mergedResults, otherResults, report =>
            {
                mergeProgress.Inner = report;
                report.TotalCount  *= 2;
                report.Message      = Localisation.Progress_Merging_Stores;
                callback(mergeProgress);
            });
            // Make sure to merge driveResults last
            mergedResults = 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);
            var infoAddCount = 0;

            foreach (var result in mergedResults)
            {
                infoAddProgress.Inner = new ListGenerationProgress(infoAddCount++, registryResults.Count, result.DisplayName ?? string.Empty);
                callback(infoAddProgress);

                InfoAdder.AddMissingInformation(result);
                result.IsValid = CheckIsValid(result, msiProducts);
            }

            // 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);
        }
        public static IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback callback)
        {
            const int totalStepCount = 8;
            var       currentStep    = 1;

            // 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();

            // Find stuff mentioned in registry
            var regProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Registry);

            callback(regProgress);
            var registryFactory = new RegistryFactory(msiProducts);
            var registryResults = registryFactory.GetUninstallerEntries(report =>
            {
                regProgress.Inner = report;
                callback(regProgress);
            }).ToList();

            // Fill in instal llocations for the drive search
            var installLocAddProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_GatherUninstallerInfo);

            callback(installLocAddProgress);
            var infoAdder          = new InfoAdderManager();
            var installLocAddCount = 0;

            foreach (var result in registryResults)
            {
                installLocAddProgress.Inner = new ListGenerationProgress(installLocAddCount++, registryResults.Count, result.DisplayName ?? string.Empty);
                callback(installLocAddProgress);

                infoAdder.AddMissingInformation(result, true);
            }

            // Look for entries on drives, based on info in registry. Need to check for duplicates with other entries later
            var driveProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_DriveScan);

            callback(driveProgress);
            var driveFactory = new DirectoryFactory(registryResults);
            var driveResults = driveFactory.GetUninstallerEntries(report =>
            {
                driveProgress.Inner = report;
                callback(driveProgress);
            }).ToList();

            // Get misc entries that use fancy logic
            var miscProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_AppStores);

            callback(miscProgress);
            var otherResults = GetMiscUninstallerEntries(report =>
            {
                miscProgress.Inner = report;
                callback(miscProgress);
            });

            // Handle duplicate entries
            var mergeProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Merging);

            callback(mergeProgress);
            var mergedResults = registryResults.ToList();

            mergedResults = MergeResults(mergedResults, otherResults, infoAdder, report =>
            {
                mergeProgress.Inner = report;
                report.TotalCount  *= 2;
                report.Message      = Localisation.Progress_Merging_Stores;
                callback(mergeProgress);
            });
            // Make sure to merge driveResults last
            mergedResults = MergeResults(mergedResults, driveResults, infoAdder, report =>
            {
                mergeProgress.Inner  = report;
                report.CurrentCount += report.TotalCount;
                report.TotalCount   *= 2;
                report.Message       = Localisation.Progress_Merging_Drives;
                callback(mergeProgress);
            });

            // Fill in any missing information
            var infoAddProgress = new ListGenerationProgress(currentStep, totalStepCount, Localisation.Progress_GeneratingInfo);

            callback(infoAddProgress);
            var infoAddCount = 0;

            foreach (var result in mergedResults)
            {
                infoAddProgress.Inner = new ListGenerationProgress(infoAddCount++, registryResults.Count, result.DisplayName ?? string.Empty);
                callback(infoAddProgress);

                infoAdder.AddMissingInformation(result);
                result.IsValid = CheckIsValid(result, msiProducts);
            }

            //callback(new GetUninstallerListProgress(currentStep, totalStepCount, "Finished"));
            return(mergedResults);
        }
        public static IEnumerable <IJunkResult> FindJunk(IEnumerable <ApplicationUninstallerEntry> targets,
                                                         ICollection <ApplicationUninstallerEntry> allUninstallers, ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            progressCallback(new ListGenerationProgress(-1, 0, Localisation.Junk_Progress_Startup));

            var scanners = ReflectionTools.GetTypesImplementingBase <IJunkCreator>()
                           .Attempt(Activator.CreateInstance)
                           .Cast <IJunkCreator>()
                           .ToList();

            foreach (var junkCreator in scanners)
            {
                junkCreator.Setup(allUninstallers);
            }

            var results       = new List <IJunkResult>();
            var targetEntries = targets as IList <ApplicationUninstallerEntry> ?? targets.ToList();
            var progress      = 0;

            foreach (var junkCreator in scanners)
            {
                var scannerProgress = new ListGenerationProgress(progress++, scanners.Count, junkCreator.CategoryName);

                var entryProgress = 0;
                foreach (var target in targetEntries)
                {
                    scannerProgress.Inner = new ListGenerationProgress(entryProgress++, targetEntries.Count, target.DisplayName);
                    progressCallback(scannerProgress);

                    try { results.AddRange(junkCreator.FindJunk(target)); }
                    catch (SystemException ex) { PremadeDialogs.GenericError(ex); }
                }
            }

            progressCallback(new ListGenerationProgress(-1, 0, Localisation.Junk_Progress_Finishing));

            foreach (var target in targetEntries)
            {
                results.AddRange(target.AdditionalJunk);
            }

            return(CleanUpResults(results));
        }
        public static IEnumerable <JunkNode> FindJunk(IEnumerable <ApplicationUninstallerEntry> uninstallers,
                                                      IEnumerable <ApplicationUninstallerEntry> allUninstallers, ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var targetEntries = uninstallers as IList <ApplicationUninstallerEntry> ?? uninstallers.ToList();

            var otherUninstallers = allUninstallers.Except(targetEntries).ToList();

            var result   = new List <JunkNode>(targetEntries.Count);
            var progress = 0;

            foreach (var uninstaller in targetEntries)
            {
                var progressInfo = new ListGenerationProgress(progress++, targetEntries.Count, uninstaller.DisplayName);

                progressInfo.Inner = new ListGenerationProgress(0, 3, "Scanning start-ups...");
                progressCallback(progressInfo);
                var sj = new StartupJunk(uninstaller);
                result.AddRange(sj.FindJunk());

                progressInfo.Inner = new ListGenerationProgress(1, 3, "Scanning drives...");
                progressCallback(progressInfo);
                var dj = new DriveJunk(uninstaller, otherUninstallers);
                result.AddRange(dj.FindJunk());

                progressInfo.Inner = new ListGenerationProgress(2, 3, "Scanning registry...");
                progressCallback(progressInfo);
                var rj = new RegistryJunk(uninstaller, otherUninstallers);
                result.AddRange(rj.FindJunk());
            }

            result.AddRange(ShortcutJunk.FindAllJunk(targetEntries, otherUninstallers));

            return(result);
        }
        private static List <ApplicationUninstallerEntry> MergeResults(ICollection <ApplicationUninstallerEntry> baseEntries,
                                                                       ICollection <ApplicationUninstallerEntry> newResults, InfoAdderManager infoAdder, ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            // Create local copy
            //var baseEntries = baseResults.ToList();
            // Add all of the base results straight away
            var results  = new List <ApplicationUninstallerEntry>(baseEntries);
            var progress = 0;

            foreach (var entry in newResults)
            {
                progressCallback(new ListGenerationProgress(progress++, newResults.Count, null));

                var matchedEntries = baseEntries.Where(x => CheckAreEntriesRelated(x, entry)).Take(2).ToList();
                if (matchedEntries.Count == 1)
                {
                    // Prevent setting incorrect UninstallerType
                    if (matchedEntries[0].UninstallPossible)
                    {
                        entry.UninstallerKind = UninstallerType.Unknown;
                    }

                    infoAdder.CopyMissingInformation(matchedEntries[0], entry);
                    continue;
                }

                // If the entry failed to match to anything, add it to the results
                results.Add(entry);
            }

            return(results);
        }
        public static IList <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback callback)
        {
            const int totalStepCount = 7;
            var       currentStep    = 1;

            var infoAdder = new InfoAdderManager();

            // 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();

            // 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 instal llocations for the drive search
                if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null)
                {
                    ApplyCache(registryResults, UninstallToolsGlobalConfig.UninstallerFactoryCache, infoAdder);
                }

                var installLocAddProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_GatherUninstallerInfo);
                callback(installLocAddProgress);
                var installLocAddCount = 0;
                foreach (var result in registryResults)
                {
                    installLocAddProgress.Inner = new ListGenerationProgress(installLocAddCount++, registryResults.Count, result.DisplayName ?? string.Empty);
                    callback(installLocAddProgress);

                    infoAdder.AddMissingInformation(result, true);
                }
            }
            else
            {
                registryResults = new List <ApplicationUninstallerEntry>();
            }

            // Look for entries on drives, based on info in registry. 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>();
            }

            // Get misc entries that use fancy logic
            var miscProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_AppStores);

            callback(miscProgress);
            var otherResults = GetMiscUninstallerEntries(report =>
            {
                miscProgress.Inner = report;
                callback(miscProgress);
            });

            // Handle duplicate entries
            var mergeProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Merging);

            callback(mergeProgress);
            var mergedResults = registryResults.ToList();

            mergedResults = MergeResults(mergedResults, otherResults, infoAdder, report =>
            {
                mergeProgress.Inner = report;
                report.TotalCount  *= 2;
                report.Message      = Localisation.Progress_Merging_Stores;
                callback(mergeProgress);
            });
            // Make sure to merge driveResults last
            mergedResults = MergeResults(mergedResults, driveResults, infoAdder, 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);
            var infoAddCount = 0;

            foreach (var result in mergedResults)
            {
                infoAddProgress.Inner = new ListGenerationProgress(infoAddCount++, registryResults.Count, result.DisplayName ?? string.Empty);
                callback(infoAddProgress);

                infoAdder.AddMissingInformation(result);
                result.IsValid = CheckIsValid(result, msiProducts);
            }

            //callback(new GetUninstallerListProgress(currentStep, totalStepCount, "Finished"));

            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);
                }
            }

            return(mergedResults);
        }
        // TODO read the app manifests for more info, requires json parsing - var manifest = Path.Combine(installDir, "current\\manifest.json");
        public IList <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var results = new List <ApplicationUninstallerEntry>();

            if (!ScoopIsAvailable)
            {
                return(results);
            }

            // Make uninstaller for scoop itself
            var scoopEntry = new ApplicationUninstallerEntry();

            scoopEntry.RawDisplayName  = "Scoop";
            scoopEntry.Comment         = "Automated program installer";
            scoopEntry.AboutUrl        = "https://github.com/lukesampson/scoop";
            scoopEntry.InstallLocation = _scoopUserPath;

            // Make sure the global directory gets removed as well
            var junk = new FileSystemJunk(new DirectoryInfo(_scoopGlobalPath), scoopEntry, null);

            junk.Confidence.Add(ConfidenceRecords.ExplicitConnection);
            junk.Confidence.Add(4);
            scoopEntry.AdditionalJunk.Add(junk);

            scoopEntry.UninstallString = MakeScoopCommand("uninstall scoop").ToString();
            scoopEntry.UninstallerKind = UninstallerType.PowerShell;
            results.Add(scoopEntry);

            // Make uninstallers for apps installed by scoop
            var result = RunScoopCommand("export");

            if (string.IsNullOrEmpty(result))
            {
                return(results);
            }

            var appEntries  = result.Split(StringTools.NewLineChars.ToArray(), StringSplitOptions.RemoveEmptyEntries);
            var exeSearcher = new AppExecutablesSearcher();

            foreach (var str in appEntries)
            {
                var startIndex  = str.IndexOf("(v:", StringComparison.Ordinal);
                var verEndIndex = str.IndexOf(')', startIndex);

                var name     = str.Substring(0, startIndex - 1);
                var version  = str.Substring(startIndex + 3, verEndIndex - startIndex - 3);
                var isGlobal = str.Substring(verEndIndex).Contains("*global*");

                var entry = new ApplicationUninstallerEntry();
                entry.RawDisplayName = name;
                entry.DisplayVersion = version;
                entry.RatingId       = "Scoop " + name;

                var installDir = Path.Combine(isGlobal ? _scoopGlobalPath : _scoopUserPath, "apps\\" + name);
                if (Directory.Exists(installDir))
                {
                    // Avoid looking for executables in old versions
                    entry.InstallLocation = Path.Combine(installDir, "current");
                    exeSearcher.AddMissingInformation(entry);

                    entry.InstallLocation = installDir;
                }

                entry.UninstallerKind = UninstallerType.PowerShell;
                entry.UninstallString = MakeScoopCommand("uninstall " + name + (isGlobal ? " --global" : "")).ToString();

                results.Add(entry);
            }

            return(results);
        }
        public IList <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var results = new List <ApplicationUninstallerEntry>();

            if (!ChocoIsAvailable)
            {
                return(results);
            }

            var result = StartProcessAndReadOutput(ChocoFullFilename, @"list -lo -nocolor --detail");

            if (string.IsNullOrEmpty(result))
            {
                return(results);
            }

            var re    = new System.Text.RegularExpressions.Regex(@"\n\w.+\r\n Title:");
            var match = re.Match(result);

            if (!match.Success)
            {
                return(results);
            }
            var begin = match.Index + 1;

            while (true)
            {
                match = match.NextMatch();
                if (!match.Success)
                {
                    break;
                }
                var end = match.Index + 1;
                var info = result.Substring(begin, end - begin);
                int i = info.IndexOf(' '), j = info.IndexOf("\r\n");
                var appName = new { name = info.Substring(0, i), version = info.Substring(i + 1, j - i - 1) };

                var kvps = ExtractPackageInformation(info);
                if (kvps.Count == 0)
                {
                    continue;
                }

                var entry = new ApplicationUninstallerEntry();

                AddInfo(entry, kvps, "Title", (e, s) => e.RawDisplayName = s);

                entry.DisplayVersion  = ApplicationEntryTools.CleanupDisplayVersion(appName.version);
                entry.RatingId        = "Choco " + appName.name;
                entry.UninstallerKind = UninstallerType.Chocolatey;

                AddInfo(entry, kvps, "Summary", (e, s) => e.Comment = s);
                if (string.IsNullOrEmpty(entry.Comment))
                {
                    AddInfo(entry, kvps, "Description", (e, s) => e.Comment = s);
                    if (string.IsNullOrEmpty(entry.Comment))
                    {
                        AddInfo(entry, kvps, "Tags", (e, s) => e.Comment = s);
                    }
                }

                AddInfo(entry, kvps, "Documentation", (e, s) => e.AboutUrl = s);
                if (string.IsNullOrEmpty(entry.AboutUrl))
                {
                    AddInfo(entry, kvps, "Software Site", (e, s) => e.AboutUrl = s);
                    if (string.IsNullOrEmpty(entry.AboutUrl))
                    {
                        AddInfo(entry, kvps, "Chocolatey Package Source", (e, s) => e.AboutUrl = s);
                    }
                }

                var psc = new ProcessStartCommand(ChocoFullFilename, $"uninstall {appName.name} -y -r");

                entry.UninstallString = psc.ToString();

                if (entry.RawDisplayName == "Chocolatey")
                {
                    entry.InstallLocation = GetChocoInstallLocation();
                }

                // Prevent chocolatey from trying to run the original uninstaller (it's deleted by now), only remove the package
                psc.Arguments += " -n --skipautouninstaller";
                var junk = new Junk.Containers.RunProcessJunk(entry, null, psc, Localisation.ChocolateyFactory_UninstallInChocolateyJunkName);
                junk.Confidence.Add(Junk.Confidence.ConfidenceRecords.ExplicitConnection);
                junk.Confidence.Add(4);
                entry.AdditionalJunk.Add(junk);

                results.Add(entry);
                begin = end;
            }

            return(results);
        }
        public IList <ApplicationUninstallerEntry> GetUninstallerEntries(
            ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var results = new List <ApplicationUninstallerEntry>();

            if (StoreAppHelperPath == null)
            {
                return(results);
            }

            var output = FactoryTools.StartHelperAndReadOutput(StoreAppHelperPath, "/query");

            if (string.IsNullOrEmpty(output))
            {
                return(results);
            }

            var windowsPath = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_WINDOWS);

            foreach (var data in FactoryTools.ExtractAppDataSetsFromHelperOutput(output))
            {
                if (!data.ContainsKey("InstalledLocation") || !Directory.Exists(data["InstalledLocation"]))
                {
                    continue;
                }

                var fullName     = data["FullName"];
                var uninstallStr = $"\"{StoreAppHelperPath}\" /uninstall \"{fullName}\"";
                var isProtected  = data.ContainsKey("IsProtected") && Convert.ToBoolean(data["IsProtected"], CultureInfo.InvariantCulture);
                var result       = new ApplicationUninstallerEntry
                {
                    Comment              = fullName,
                    CacheIdOverride      = fullName,
                    RatingId             = fullName.Substring(0, fullName.IndexOf("_", StringComparison.Ordinal)),
                    UninstallString      = uninstallStr,
                    QuietUninstallString = uninstallStr,
                    RawDisplayName       = string.IsNullOrEmpty(data["DisplayName"]) ? fullName : data["DisplayName"],
                    Publisher            = data["PublisherDisplayName"],
                    IsValid              = true,
                    UninstallerKind      = UninstallerType.StoreApp,
                    InstallLocation      = data["InstalledLocation"],
                    InstallDate          = Directory.GetCreationTime(data["InstalledLocation"]),
                    IsProtected          = isProtected,
                    SystemComponent      = isProtected
                };

                if (File.Exists(data["Logo"]))
                {
                    try
                    {
                        result.DisplayIcon = data["Logo"];
                        result.IconBitmap  = DrawingTools.IconFromImage(new Bitmap(data["Logo"]));
                    }
                    catch
                    {
                        result.DisplayIcon = null;
                        result.IconBitmap  = null;
                    }
                }

                if (result.InstallLocation.StartsWith(windowsPath, StringComparison.InvariantCultureIgnoreCase))
                {
                    result.SystemComponent = true;
                    //result.IsProtected = true;
                }

                results.Add(result);
            }

            return(results);
        }
Example #28
0
        // TODO read the app manifests for more info, requires json parsing - var manifest = Path.Combine(installDir, "current\\manifest.json");
        public IList <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            var results = new List <ApplicationUninstallerEntry>();

            if (!ScoopIsAvailable)
            {
                return(results);
            }

            // Make uninstaller for scoop itself
            var scoopEntry = new ApplicationUninstallerEntry
            {
                RawDisplayName  = "Scoop",
                Comment         = "Automated program installer",
                AboutUrl        = "https://github.com/lukesampson/scoop",
                InstallLocation = _scoopUserPath
            };

            // Make sure the global directory gets removed as well
            var junk = new FileSystemJunk(new DirectoryInfo(_scoopGlobalPath), scoopEntry, null);

            junk.Confidence.Add(ConfidenceRecords.ExplicitConnection);
            junk.Confidence.Add(4);
            scoopEntry.AdditionalJunk.Add(junk);

            scoopEntry.UninstallString = MakeScoopCommand("uninstall scoop").ToString();
            scoopEntry.UninstallerKind = UninstallerType.PowerShell;
            results.Add(scoopEntry);

            // Make uninstallers for apps installed by scoop
            var result = RunScoopCommand("export");

            if (string.IsNullOrEmpty(result))
            {
                return(results);
            }

            var appEntries  = result.Split(StringTools.NewLineChars.ToArray(), StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim());
            var exeSearcher = new AppExecutablesSearcher();

            foreach (var str in appEntries)
            {
                // Format should be "$app (v:$ver) $global_display $bucket $arch"
                // app has no spaces, $global_display is *global*, bucket is inside [] brackets like [main]
                // version should always be there but the check errored out for some users, everything after version is optional
                string name;
                string version    = null;
                bool   isGlobal   = false;
                var    spaceIndex = str.IndexOf(" ", StringComparison.Ordinal);
                if (spaceIndex > 0)
                {
                    name = str.Substring(0, spaceIndex);

                    var startIndex = str.IndexOf("(v:", StringComparison.Ordinal);
                    if (startIndex > 0)
                    {
                        var verEndIndex = str.IndexOf(')', startIndex);
                        version = str.Substring(Math.Min(startIndex + 3, str.Length - 1), Math.Max(verEndIndex - startIndex - 3, 0));
                        if (version.Length == 0)
                        {
                            version = null;
                        }
                    }
                    isGlobal = str.Substring(spaceIndex).Contains("*global*");
                }
                else
                {
                    name = str;
                }

                var entry = new ApplicationUninstallerEntry
                {
                    RawDisplayName = name,
                    DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(version),
                    RatingId       = "Scoop " + name
                };

                var installDir = Path.Combine(isGlobal ? _scoopGlobalPath : _scoopUserPath, "apps\\" + name);
                if (Directory.Exists(installDir))
                {
                    // Avoid looking for executables in old versions
                    entry.InstallLocation = Path.Combine(installDir, "current");
                    exeSearcher.AddMissingInformation(entry);

                    entry.InstallLocation = installDir;
                }

                entry.UninstallerKind = UninstallerType.PowerShell;
                entry.UninstallString = MakeScoopCommand("uninstall " + name + (isGlobal ? " --global" : "")).ToString();

                results.Add(entry);
            }

            return(results);
        }
Example #29
0
        public IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            if (!ChocoIsAvailable)
            {
                yield break;
            }

            var result = StartProcessAndReadOutput(ChocoLocation, @"list -l -nocolor -y -r");

            if (string.IsNullOrEmpty(result))
            {
                yield break;
            }

            var appEntries = result.Split(NewlineSeparators, StringSplitOptions.RemoveEmptyEntries);
            var appNames   = appEntries.Select(x =>
            {
                var i = x.IndexOf('|');
                if (i <= 0)
                {
                    return(null);
                }
                return(new { name = x.Substring(0, i), version = x.Substring(i + 1) });
            }).Where(x => x != null);

            foreach (var appName in appNames)
            {
                var info = StartProcessAndReadOutput(ChocoLocation, "info -l -nocolor -y -v " + appName.name);
                var kvps = ExtractPackageInformation(info);
                if (kvps.Count == 0)
                {
                    continue;
                }

                var entry = new ApplicationUninstallerEntry();

                AddInfo(entry, kvps, "Title", (e, s) => e.RawDisplayName = s);

                entry.DisplayVersion  = appName.version;
                entry.RatingId        = "Choco " + appName.name;
                entry.UninstallerKind = UninstallerType.Chocolatey;

                AddInfo(entry, kvps, "Summary", (e, s) => e.Comment = s);
                if (string.IsNullOrEmpty(entry.Comment))
                {
                    AddInfo(entry, kvps, "Description", (e, s) => e.Comment = s);
                    if (string.IsNullOrEmpty(entry.Comment))
                    {
                        AddInfo(entry, kvps, "Tags", (e, s) => e.Comment = s);
                    }
                }

                AddInfo(entry, kvps, "Documentation", (e, s) => e.AboutUrl = s);
                if (string.IsNullOrEmpty(entry.AboutUrl))
                {
                    AddInfo(entry, kvps, "Software Site", (e, s) => e.AboutUrl = s);
                    if (string.IsNullOrEmpty(entry.AboutUrl))
                    {
                        AddInfo(entry, kvps, "Chocolatey Package Source", (e, s) => e.AboutUrl = s);
                    }
                }

                var psc = new ProcessStartCommand(ChocoLocation, $"uninstall {appName.name} -y -r");

                entry.UninstallString = psc.ToString();

                // Prevent chocolatey from trying to run the original uninstaller (it's deleted by now), only remove the package
                psc.Arguments += " -n --skipautouninstaller";
                var junk = new Junk.Containers.RunProcessJunk(entry, null, psc, Localisation.ChocolateyFactory_UninstallInChocolateyJunkName);
                junk.Confidence.Add(Junk.Confidence.ConfidenceRecords.ExplicitConnection);
                entry.AdditionalJunk.Add(junk);

                yield return(entry);
            }
        }
        public IEnumerable <ApplicationUninstallerEntry> GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback)
        {
            if (!Directory.Exists(ScriptDir))
            {
                yield break;
            }

            var manifests = Directory.GetFiles(ScriptDir, "*.xml", SearchOption.AllDirectories);

            foreach (var manifest in manifests)
            {
                var contents = TryGetContents(manifest);

                if (contents == null || !contents.HasElements)
                {
                    continue;
                }

                var manifestDirectoryName = Path.GetDirectoryName(manifest);

                var conditionScript = contents.Element("ConditionScript")?.Value;
                if (!string.IsNullOrEmpty(conditionScript))
                {
                    var psc = MakePsCommand(manifestDirectoryName, conditionScript, contents.Element("ConditionScriptArgs")?.Value, true);
                    if (!string.IsNullOrEmpty(psc))
                    {
                        if (!PowershellExists || !CheckCondition(psc))
                        {
                            continue;
                        }
                    }
                }

                var entry = new ApplicationUninstallerEntry();

                // Automatically fill in any supplied static properties
                foreach (var entryProp in EntryProps)
                {
                    var item = contents.Element(entryProp.Name)?.Value;
                    if (item != null)
                    {
                        try
                        {
                            const string registryHeader = "Registry::";
                            if (item.StartsWith(registryHeader, StringComparison.OrdinalIgnoreCase))
                            {
                                var fullPath = item.Substring(registryHeader.Length);
                                item = RegistryTools.OpenRegistryKey(Path.GetDirectoryName(fullPath))
                                       ?.GetValue(Path.GetFileName(fullPath))
                                       ?.ToString();
                            }

                            entryProp.SetValue(entry, item, null);
                        }
                        catch (SystemException ex)
                        {
                            Console.WriteLine(ex);
                        }
                    }
                }

                // Override any static uninstall strings if valid script is supplied
                var script = contents.Element("Script")?.Value;
                if (!string.IsNullOrEmpty(script))
                {
                    var scriptArgs = contents.Element("ScriptArgs")?.Value;
                    var psc        = MakePsCommand(manifestDirectoryName, script, scriptArgs, false);
                    if (!string.IsNullOrEmpty(psc))
                    {
                        if (!PowershellExists)
                        {
                            continue;
                        }

                        entry.UninstallString      = psc;
                        entry.QuietUninstallString = MakePsCommand(manifestDirectoryName, script, scriptArgs, true);
                        entry.UninstallerKind      = UninstallerType.PowerShell;
                    }
                }

                if (entry.UninstallPossible || entry.QuietUninstallPossible)
                {
                    if (string.IsNullOrEmpty(entry.DisplayName))
                    {
                        entry.DisplayName = Path.GetFileNameWithoutExtension(manifest);
                    }
                    if (string.IsNullOrEmpty(entry.Publisher))
                    {
                        entry.Publisher = "Script";
                    }

                    var icon = contents.Element("SystemIcon")?.Value;
                    if (!string.IsNullOrEmpty(icon))
                    {
                        var iconObj = SystemIconProps.FirstOrDefault(p => p.Name.Equals(icon, StringComparison.OrdinalIgnoreCase))
                                      ?.GetValue(null, null) as Icon;
                        entry.IconBitmap = iconObj;
                    }

                    if (string.IsNullOrEmpty(entry.RatingId))
                    {
                        entry.RatingId = manifest.Remove(0, ScriptDir.Length).Trim(' ', '\\', '/').ToLowerInvariant().Replace(".xml", "", StringComparison.Ordinal);
                    }

                    yield return(entry);
                }
            }
        }