/// <summary>
        /// Get directories which are already used and should be skipped
        /// </summary>
        private static IEnumerable <string> GetDirectoriesToSkip(IEnumerable <ApplicationUninstallerEntry> existingUninstallers,
                                                                 IEnumerable <KVP> pfDirectories)
        {
            var dirs = new List <string>();

            foreach (var x in existingUninstallers)
            {
                dirs.Add(x.InstallLocation);
                dirs.Add(x.UninstallerLocation);

                if (string.IsNullOrEmpty(x.DisplayIcon))
                {
                    continue;
                }
                try
                {
                    var iconFilename = x.DisplayIcon.Contains('.')
                        ? ProcessTools.SeparateArgsFromCommand(x.DisplayIcon).FileName
                        : x.DisplayIcon;

                    dirs.Add(PathTools.GetDirectory(iconFilename));
                }
                catch
                {
                    // Ignore invalid DisplayIcon paths
                }
            }

            return(dirs.Where(x => !string.IsNullOrEmpty(x)).Distinct()
                   .Where(x => !pfDirectories.Any(pfd => pfd.Key.FullName.Contains(x, StringComparison.InvariantCultureIgnoreCase))));
        }
        public static int UninstallUsingMsi(this ApplicationUninstallerEntry entry, MsiUninstallModes mode,
                                            bool simulate)
        {
            try
            {
                var uninstallPath = GetMsiString(entry.BundleProviderKey, mode);
                if (string.IsNullOrEmpty(uninstallPath))
                {
                    return(-1);
                }

                var startInfo = ProcessTools.SeparateArgsFromCommand(uninstallPath).ToProcessStartInfo();
                startInfo.UseShellExecute = false;
                if (simulate)
                {
                    Thread.Sleep(SimulationDelay);
                    return(0);
                }
                return(startInfo.StartAndWait());
            }
            catch (IOException)
            {
                throw;
            }
            catch (InvalidOperationException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FormatException(ex.Message, ex);
            }
        }
        private static string CleanupPath(string path, bool isFilename = false)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(null);
            }

            if (!isFilename)
            {
                // Try the fast method first for directories
                var trimmed = path.Trim('"', ' ', '\'', '\\', '/');

                if (!trimmed.ContainsAny(InvalidPathChars))
                {
                    return(trimmed);
                }
            }

            try
            {
                path = ProcessTools.SeparateArgsFromCommand(path).FileName;
                if (!isFilename && path.Contains('.') && !Directory.Exists(path))
                {
                    return(Path.GetDirectoryName(path));
                }
            }
            catch
            {
                // If sanitization failed just leave it be, it will be handled afterwards
            }
            return(path.TrimEnd('\\'));
        }
        public static int Modify(this ApplicationUninstallerEntry entry, bool simulate)
        {
            try
            {
                if (string.IsNullOrEmpty(entry.ModifyPath))
                {
                    return(-1);
                }

                var startInfo = ProcessTools.SeparateArgsFromCommand(entry.ModifyPath).ToProcessStartInfo();
                startInfo.UseShellExecute = false;
                if (simulate)
                {
                    Thread.Sleep(SimulationDelay);
                    return(0);
                }
                return(startInfo.StartAndWait());
            }
            catch (IOException)
            {
                throw;
            }
            catch (InvalidOperationException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FormatException(ex.Message, ex);
            }
        }
        private static bool CheckCondition(string psc)
        {
            try
            {
                var startInfo = ProcessTools.SeparateArgsFromCommand(psc).ToProcessStartInfo();
                startInfo.CreateNoWindow = true;
                startInfo.ErrorDialog    = false;
                startInfo.WindowStyle    = ProcessWindowStyle.Hidden;

                var p = Process.Start(startInfo);
                if (p == null)
                {
                    return(false);
                }

                if (!p.WaitForExit(5000))
                {
                    Console.WriteLine(@"Script's ConditionScript command timed out - " + psc);
                    p.Kill();
                    return(false);
                }

                return(p.ExitCode == 0);
            }
            catch (SystemException ex)
            {
                Console.WriteLine($@"Failed to test script condition ""{psc}"" - {ex.Message}");
                return(false);
            }
        }
Exemple #6
0
        private static void RunExternalCommands(string commands, LoadingDialogInterface controller)
        {
            var lines = commands.SplitNewlines(StringSplitOptions.RemoveEmptyEntries);

            controller.SetMaximum(lines.Length);

            for (var i = 0; i < lines.Length; i++)
            {
                controller.SetProgress(i);

                var line = lines[i];
                try
                {
                    var filename = ProcessTools.SeparateArgsFromCommand(line);
                    filename.FileName = Path.GetFullPath(filename.FileName);
                    if (!File.Exists(filename.FileName))
                    {
                        throw new IOException(Localisable.Error_FileNotFound);
                    }
                    filename.ToProcessStartInfo().StartAndWait();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format(Localisable.MessageBoxes_ExternalCommandFailed_Message, line)
                                    + Localisable.MessageBoxes_Error_details + ex.Message,
                                    Localisable.MessageBoxes_ExternalCommandFailed_Title,
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        public ServiceEntry(string serviceName, string displayName, string command)
        {
            ProgramName   = serviceName;
            EntryLongName = displayName;

            Command         = command;
            CommandFilePath = ProcessTools.SeparateArgsFromCommand(command).FileName;

            FillInformationFromFile(CommandFilePath);
        }
        /// <summary>
        ///     Generate missing quiet commands if possible
        /// </summary>
        /// <param name="entries">Entries to generate the quiet commands for</param>
        /// <param name="automatizerKillstuck">
        ///     Generated entries should kill the process if it gets stuck waiting for user input or
        ///     the process otherwise fails
        /// </param>
        public static void GenerateQuietCommands(IEnumerable <ApplicationUninstallerEntry> entries,
                                                 bool automatizerKillstuck)
        {
            if (!File.Exists(UninstallerAutomatizerPath))
            {
                return;
            }

            var nsisCommandStart = $"\"{UninstallerAutomatizerPath}\" {UninstallerType.Nsis} ";

            if (automatizerKillstuck)
            {
                nsisCommandStart = nsisCommandStart.Append("/K ");
            }

            foreach (var uninstallerEntry in entries)
            {
                if (uninstallerEntry.QuietUninstallPossible || !uninstallerEntry.UninstallPossible)
                {
                    continue;
                }

                switch (uninstallerEntry.UninstallerKind)
                {
                case UninstallerType.Nsis:
                    uninstallerEntry.QuietUninstallString = nsisCommandStart + uninstallerEntry.UninstallString;
                    break;

                case UninstallerType.InnoSetup:
                    try
                    {
                        // Get rid of quotes and arguments that are already there for some weird reason (InnoSetup doesn't need any arguments)
                        uninstallerEntry.QuietUninstallString =
                            $"\"{ProcessTools.SeparateArgsFromCommand(uninstallerEntry.UninstallString).FileName}\" /SILENT";
                    }
                    catch (ArgumentException)
                    {
                    }
                    catch (FormatException)
                    {
                    }
                    break;
                }
            }
        }
        public static string ExtractFullFilename(string uninstallString)
        {
            if (!string.IsNullOrEmpty(uninstallString))
            {
                try
                {
                    var fileName = ProcessTools.SeparateArgsFromCommand(uninstallString).FileName;

                    Debug.Assert(!string.IsNullOrEmpty(fileName?.Trim()),
                                 $@"SeparateArgsFromCommand failed for {fileName}");

                    return(fileName);
                }
                catch (ArgumentException) { }
                catch (FormatException) { }
            }

            return(null);
        }
Exemple #10
0
        private static string GetUninstallerFilename(string uninstallString)
        {
            if (!string.IsNullOrEmpty(uninstallString))
            {
                try
                {
                    var fileName = ProcessTools.SeparateArgsFromCommand(uninstallString).FileName;

                    Debug.Assert(!fileName.Contains(' ') || File.Exists(fileName),
                                 $@"SeparateArgsFromCommand failed for {fileName}, or it doesn't exist");

                    return(fileName);
                }
                catch (ArgumentException) { }
                catch (FormatException) { }
            }

            return(string.Empty);
        }
Exemple #11
0
        /// <summary>
        ///  Convert path to a directory string usable for grouping
        /// </summary>
        private static string GetFuzzyDirectory(string fullCommand)
        {
            if (string.IsNullOrEmpty(fullCommand))
            {
                return(Localisable.Empty);
            }

            if (fullCommand.StartsWith("msiexec", StringComparison.OrdinalIgnoreCase) ||
                fullCommand.Contains("msiexec.exe", StringComparison.OrdinalIgnoreCase))
            {
                return("MsiExec");
            }

            try
            {
                if (fullCommand.Contains('\\'))
                {
                    string strOut;
                    try
                    {
                        strOut = ProcessTools.SeparateArgsFromCommand(fullCommand).FileName;
                    }
                    catch
                    {
                        strOut = fullCommand;
                    }

                    strOut = Path.GetDirectoryName(strOut);

                    strOut = PathTools.GetPathUpToLevel(strOut, 1, false);
                    if (strOut.IsNotEmpty())
                    {
                        return(PathTools.PathToNormalCase(strOut)); //Path.GetFullPath(strOut);
                    }
                }
            }
            catch
            {
                // Assume path is invalid
            }
            return(Localisable.Empty);
        }
Exemple #12
0
        public void AddMissingInformation(ApplicationUninstallerEntry entry)
        {
            if (entry.IconBitmap != null)
            {
                return;
            }

            // Check for any specified icons
            if (!string.IsNullOrEmpty(entry.DisplayIcon) &&
                !ApplicationEntryTools.PathPointsToMsiExec(entry.DisplayIcon))
            {
                string resultFilename = null;

                if (File.Exists(entry.DisplayIcon))
                {
                    resultFilename = entry.DisplayIcon;
                }

                if (resultFilename == null)
                {
                    try
                    {
                        var fName = ProcessTools.SeparateArgsFromCommand(entry.DisplayIcon).FileName;
                        if (fName != null && File.Exists(fName))
                        {
                            resultFilename = fName;
                        }
                    }
                    catch
                    {
                        // Ignore error and try another method
                    }
                }

                var icon = UninstallToolsGlobalConfig.TryExtractAssociatedIcon(resultFilename);
                if (icon != null)
                {
                    entry.DisplayIcon = resultFilename;
                    entry.IconBitmap  = icon;
                }
            }
        }
        private void ProcessFiles(ICollection <string> files)
        {
            if (files == null || files.Count < 1)
            {
                return;
            }

            var folders = new List <string>();

            foreach (var file in files)
            {
                var fname = file;

                if (string.IsNullOrEmpty(fname))
                {
                    continue;
                }

RewindDropLoop:

                if (Directory.Exists(fname))
                {
                    folders.Add(fname);
                    continue;
                }

                if (!File.Exists(fname))
                {
                    try
                    {
                        fname = ProcessTools.SeparateArgsFromCommand(file).FileName;

                        if (Directory.Exists(fname))
                        {
                            folders.Add(fname);
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                }

                if (fname.TrimEnd().EndsWith(".lnk", StringComparison.OrdinalIgnoreCase))
                {
                    try
                    {
                        var result = WindowsTools.ResolveShortcut(fname);
                        if (result != null)
                        {
                            fname = result;
                            goto RewindDropLoop;
                        }
                    }
                    catch (Exception ex)
                    {
                        PremadeDialogs.GenericError(ex);
                    }
                }
                else
                {
                    try
                    {
                        var dirName = Path.GetDirectoryName(fname);
                        folders.Add(dirName);
                    }
                    catch (Exception ex)
                    {
                        PremadeDialogs.GenericError(ex);
                    }
                }
            }

            var distinctFolders = folders.Where(x => x != null)
                                  .Select(x => x.Normalize().ToLowerInvariant().Trim().Trim('\'', '"').Trim())
                                  .Distinct();

            var folderInfos = distinctFolders.Select(x =>
            {
                try
                {
                    return(new DirectoryInfo(x));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    return(null);
                }
            }).Where(x => x != null);

            var results = folderInfos.Where(x => !UninstallToolsGlobalConfig.IsSystemDirectory(x)).ToList();

            DirectoriesSelected?.Invoke(this, new DirectoriesSelectedEventArgs(results));
        }
        public static Process RunUninstaller(this ApplicationUninstallerEntry entry, bool silentIfAvailable, bool simulate, bool safeMode = false)
        {
            try
            {
                ProcessStartInfo startInfo = null;
                string           fallBack  = null;

                if (silentIfAvailable && entry.QuietUninstallPossible)
                {
                    // Use supplied quiet uninstaller if any
                    try
                    {
                        startInfo = ProcessTools.SeparateArgsFromCommand(entry.QuietUninstallString).ToProcessStartInfo();
                        Debug.Assert(!startInfo.FileName.Contains(' ') || File.Exists(startInfo.FileName));
                    }
                    catch (FormatException)
                    {
                        fallBack = entry.QuietUninstallString;
                    }
                }
                else if (entry.UninstallPossible)
                {
                    // Fall back to the non-quiet uninstaller
                    try
                    {
                        startInfo = ProcessTools.SeparateArgsFromCommand(entry.UninstallString).ToProcessStartInfo();
                        Debug.Assert(!startInfo.FileName.Contains(' ') || File.Exists(startInfo.FileName));

                        if (entry.UninstallerKind == UninstallerType.Nsis && !safeMode)
                        {
                            UpdateNsisStartInfo(startInfo, entry.DisplayName);
                        }
                    }
                    catch (FormatException)
                    {
                        fallBack = entry.UninstallString;
                    }
                }
                else
                {
                    // Cant do shit, capt'n
                    throw new InvalidOperationException(Localisation.UninstallError_Nowaytouninstall);
                }

                if (simulate)
                {
                    Thread.Sleep(SimulationDelay);
                    if (Debugger.IsAttached && new Random().Next(0, 2) == 0)
                    {
                        throw new IOException("Random failure for debugging");
                    }
                    return(null);
                }

                if (fallBack != null)
                {
                    return(Process.Start(fallBack));
                }

                if (startInfo != null)
                {
                    startInfo.UseShellExecute = true;
                    return(Process.Start(startInfo));
                }

                // Cant do shit, capt'n
                throw new InvalidOperationException(Localisation.UninstallError_Nowaytouninstall);
            }
            catch (IOException)
            {
                throw;
            }
            catch (InvalidOperationException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FormatException(ex.Message, ex);
            }
        }
        public void Start()
        {
            var args = Environment.GetCommandLineArgs().Skip(1).ToArray();

            if (args.Length == 1 && args[0].Equals("/d", StringComparison.OrdinalIgnoreCase))
            {
                StartDaemon();
                return;
            }

            IsDaemon = false;

            if (args.Length < 2)
            {
                Program.ReturnValue = ReturnValue.InvalidArgumentCode;
                OnStatusUpdate(new UninstallHandlerUpdateArgs(UninstallHandlerUpdateKind.Failed, Localization.Error_Invalid_number_of_arguments));
                return;
            }

            UninstallerType uType;

            if (!Enum.TryParse(args[0], out uType))
            {
                Program.ReturnValue = ReturnValue.InvalidArgumentCode;
                OnStatusUpdate(new UninstallHandlerUpdateArgs(UninstallHandlerUpdateKind.Failed, string.Format(Localization.Error_UnknownUninstallerType, args[0])));
                return;
            }

            args = args.Skip(1).ToArray();

            if (args[0].Equals("/k", StringComparison.InvariantCultureIgnoreCase))
            {
                args       = args.Skip(1).ToArray();
                KillOnFail = true;
            }

            UninstallTarget = string.Join(" ", args);


            if (!File.Exists(ProcessTools.SeparateArgsFromCommand(UninstallTarget).FileName))
            {
                Program.ReturnValue = ReturnValue.InvalidArgumentCode;
                OnStatusUpdate(new UninstallHandlerUpdateArgs(UninstallHandlerUpdateKind.Failed, string.Format(Localization.Error_InvalidPath, UninstallTarget)));
                return;
            }

            if (uType != UninstallerType.Nsis)
            {
                Program.ReturnValue = ReturnValue.InvalidArgumentCode;
                OnStatusUpdate(new UninstallHandlerUpdateArgs(UninstallHandlerUpdateKind.Failed, string.Format(Localization.Error_NotSupported, uType)));
                return;
            }

            OnStatusUpdate(new UninstallHandlerUpdateArgs(UninstallHandlerUpdateKind.Normal, string.Format(Localization.Message_Starting, UninstallTarget)));

            _automationThread = new Thread(AutomationThread)
            {
                Name = "AutomationThread", IsBackground = false, Priority = ThreadPriority.AboveNormal
            };
            _automationThread.Start();
        }
        public static IEnumerable <ApplicationUninstallerEntry> GetApplicationsFromDrive(
            IEnumerable <ApplicationUninstallerEntry> existingUninstallerEntries, GetUninstallerListCallback callback)
        {
            var existingUninstallers = existingUninstallerEntries as IList <ApplicationUninstallerEntry> ??
                                       existingUninstallerEntries.ToList();

            var pfDirectories = UninstallToolsGlobalConfig.GetProgramFilesDirectories(true).ToList();

            // Get directories which are already used and should be skipped
            var directoriesToSkip = existingUninstallers.SelectMany(x =>
            {
                if (!string.IsNullOrEmpty(x.DisplayIcon))
                {
                    try
                    {
                        var iconFilename = x.DisplayIcon.Contains('.')
                            ? ProcessTools.SeparateArgsFromCommand(x.DisplayIcon).FileName
                            : x.DisplayIcon;

                        return(new[] { x.InstallLocation, x.UninstallerLocation, PathTools.GetDirectory(iconFilename) });
                    }
                    catch
                    {
                        // Ignore invalid DisplayIcon paths
                    }
                }
                return(new[] { x.InstallLocation, x.UninstallerLocation });
            }).Where(x => x.IsNotEmpty()).Select(PathTools.PathToNormalCase)
                                    .Where(x => !pfDirectories.Any(pfd => pfd.Key.FullName.Contains(x, StringComparison.InvariantCultureIgnoreCase)))
                                    .Distinct().ToList();

            // Get sub directories which could contain user programs
            var directoriesToCheck = pfDirectories.Aggregate(Enumerable.Empty <KeyValuePair <DirectoryInfo, bool?> >(),
                                                             (a, b) => a.Concat(b.Key.GetDirectories().Select(x => new KeyValuePair <DirectoryInfo, bool?>(x, b.Value))));

            // Get directories that can be relatively safely checked
            var inputs = directoriesToCheck.Where(x => !directoriesToSkip.Any(y =>
                                                                              x.Key.FullName.Contains(y, StringComparison.InvariantCultureIgnoreCase) ||
                                                                              y.Contains(x.Key.FullName, StringComparison.InvariantCultureIgnoreCase))).ToList();

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

            foreach (var directory in inputs)
            {
                itemId++;

                var progress = new GetUninstallerListProgress(inputs.Count)
                {
                    CurrentCount = itemId
                };
                callback(progress);

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

                //Try to get the main executable from the filtered folders. If no executables are present check subfolders.
                var detectedEntries = ApplicationUninstallerFactory.TryCreateFromDirectory(directory.Key,
                                                                                           directory.Value);

                results.AddRange(detectedEntries.Where(detected => !existingUninstallers.Any(existing =>
                {
                    if (!string.IsNullOrEmpty(existing.DisplayName) && !string.IsNullOrEmpty(detected.DisplayNameTrimmed) &&
                        existing.DisplayName.Contains(detected.DisplayNameTrimmed))
                    {
                        return(!existing.IsInstallLocationValid() ||
                               detected.InstallLocation.Contains(existing.InstallLocation,
                                                                 StringComparison.CurrentCultureIgnoreCase));
                    }
                    return(false);
                })));

                //if (result != null && !existingUninstallers.Any(x => x.DisplayName.Contains(result.DisplayNameTrimmed)))
                //    results.Add(result);
            }

            return(results);
        }