예제 #1
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();

            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);
        }
        private static void CreateFromDirectoryHelper(ICollection <ApplicationUninstallerEntry> results,
                                                      DirectoryInfo directory, int level, ICollection <string> dirsToSkip)
        {
            // Level 0 is for the pf folder itself. First subfolder is level 1.
            if (level > 2 || dirsToSkip.Any(x => directory.FullName.Contains(x, StringComparison.InvariantCultureIgnoreCase)))
            {
                return;
            }

            // Get contents of this installDir
            AppExecutablesSearcher.ScanDirectoryResult result;

            try
            {
                result = AppExecutablesSearcher.ScanDirectory(directory);
            }
            catch (IOException)
            {
                return;
            }
            catch (UnauthorizedAccessException)
            {
                return;
            }

            // Check if it is potentially dangerous to process this installDir.
            if (result.ExecutableFiles.Count > 40)
            {
                return;
            }

            var anyFiles = result.ExecutableFiles.Any();

            if (!anyFiles && !result.BinSubdirs.Any())
            {
                foreach (var dir in result.OtherSubdirs)
                {
                    CreateFromDirectoryHelper(results, dir, level + 1, dirsToSkip);
                }
            }
            else if (anyFiles)
            {
                var entry = new ApplicationUninstallerEntry();

                // Parse directories into useful information
                if (level > 0 && directory.Name.StartsWithAny(AppExecutablesSearcher.BinaryDirectoryNames, StringComparison.OrdinalIgnoreCase))
                {
                    entry.InstallLocation = directory.Parent?.FullName;
                    entry.RawDisplayName  = directory.Parent?.Name;
                }
                else
                {
                    entry.InstallLocation = directory.FullName;
                    entry.RawDisplayName  = directory.Name;

                    if (level > 0)
                    {
                        entry.Publisher = directory.Parent?.Name;
                    }
                }

                var sorted = AppExecutablesSearcher.SortListExecutables(result.ExecutableFiles, entry.DisplayNameTrimmed).ToArray();
                entry.SortedExecutables = sorted.Select(x => x.FullName).ToArray();

                entry.InstallDate = directory.CreationTime;
                //entry.IconBitmap = TryExtractAssociatedIcon(compareBestMatchFile.FullName);

                // Extract info from file metadata and overwrite old values
                var compareBestMatchFile = sorted.First();
                ExecutableAttributeExtractor.FillInformationFromFileAttribs(entry, compareBestMatchFile.FullName, false);

                results.Add(entry);
            }
        }
예제 #3
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);
        }