Example #1
0
        public void serialize <XmlType>(XmlType xmlType, string xmlFilePath)
        {
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(xmlFilePath));
            try
            {
                if (_fileSystem.file_exists(xmlFilePath))
                {
                    _fileSystem.delete_file(xmlFilePath);
                }

                var xmlSerializer = new XmlSerializer(typeof(XmlType));
                var textWriter    = new StreamWriter(xmlFilePath, append: false, encoding: Encoding.UTF8)
                {
                    AutoFlush = true
                };

                xmlSerializer.Serialize(textWriter, xmlType);
                textWriter.Flush();

                textWriter.Close();
                textWriter.Dispose();
            }
            catch (Exception ex)
            {
                this.Log().Error("Error serializing type {0}:{1}{2}", typeof(XmlType), Environment.NewLine, Config.get_configuration_settings().Debug ? ex.ToString() : ex.Message);
                throw;
            }
        }
        private void handle_message(PreRunMessage message)
        {
            this.Log().Debug(ChocolateyLoggers.Verbose, "[Pending] Removing all pending packages that should not be considered installed...");

            var pendingFiles = _fileSystem.get_files(ApplicationParameters.PackagesLocation, ApplicationParameters.PackagePendingFileName, SearchOption.AllDirectories).ToList();

            foreach (var pendingFile in pendingFiles.or_empty_list_if_null())
            {
                var packageFolder     = _fileSystem.get_directory_name(pendingFile);
                var packageFolderName = _fileSystem.get_directory_info_for(packageFolder).Name;

                var pendingSkipFiles = _fileSystem.get_files(packageFolder, PENDING_SKIP_FILE, SearchOption.AllDirectories).ToList();
                if (pendingSkipFiles.Count != 0)
                {
                    this.Log().Warn("Pending file found for {0}, but a {1} file was also found. Skipping removal".format_with(packageFolderName, PENDING_SKIP_FILE));
                    continue;
                }

                // wait for the file to be at least x seconds old
                // this allows commands running from the package for configuring sources, etc
                var fileInfo = _fileSystem.get_file_info_for(pendingFile);
                if (fileInfo.CreationTimeUtc.AddSeconds(PENDING_FILE_AGE_SECONDS) > _dateTimeService.get_current_date_time())
                {
                    this.Log().Debug("Pending file found for {0}, but the file is not {1} seconds old yet.".format_with(packageFolderName, PENDING_FILE_AGE_SECONDS));
                    continue;
                }

                this.Log().Warn("[Pending] Removing incomplete install for '{0}'".format_with(packageFolderName));
                FaultTolerance.retry(2, () => _fileSystem.delete_directory_if_exists(packageFolder, recursive: true, overrideAttributes: true, isSilent: true), 500, isSilent: true);
            }
        }
Example #3
0
        private TestCommandOutputResult execute_vagrant(string command)
        {
            this.Log().Debug(() => "Executing vagrant command '{0}'.".format_with(command.escape_curly_braces()));
            var results = new TestCommandOutputResult();
            var logs    = new StringBuilder();

            var output = _commandExecutor.execute(
                _vagrantExecutable,
                command,
                _configuration.CommandExecutionTimeoutSeconds + 60,
                _fileSystem.get_directory_name(Assembly.GetExecutingAssembly().Location),
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Info(() => " [Vagrant] {0}".format_with(e.Data));
                logs.AppendLine(e.Data);
                results.Messages.Add(
                    new ResultMessage
                {
                    Message     = e.Data,
                    MessageType = ResultType.Note
                });
            },
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Warn(() => " [Vagrant][Error] {0}".format_with(e.Data));
                logs.AppendLine("[ERROR] " + e.Data);
                results.Messages.Add(
                    new ResultMessage
                {
                    Message     = e.Data,
                    MessageType = ResultType.Note
                });
            },
                updateProcessPath: false,
                allowUseWindow: false);

            //if (!string.IsNullOrWhiteSpace(output.StandardError))
            //{
            //    results.Messages.Add(new ResultMessage { Message = output.StandardError, MessageType = ResultType.Error });
            //    logs.Append("##Error Output" + Environment.NewLine);
            //    logs.Append(output.StandardError + Environment.NewLine + Environment.NewLine);
            //}

            //results.Messages.Add(new ResultMessage { Message = output.StandardOut, MessageType = ResultType.Note });
            //logs.Append("##Standard Output" + Environment.NewLine);
            //logs.Append(output.StandardOut);

            results.Logs     = logs.ToString();
            results.ExitCode = output;

            return(results);
        }
Example #4
0
        public ShellView(
            IDialogService dialogService,
            IProgressService progressService,
            IChocolateyConfigurationProvider chocolateyConfigurationProvider,
            IConfigService configService,
            IFileSystem fileSystem,
            IImageService imageService)
        {
            InitializeComponent();

            dialogService.ShellView   = this;
            progressService.ShellView = this;

            _progressService = progressService;
            _chocolateyConfigurationProvider = chocolateyConfigurationProvider;
            _configService = configService;
            _fileSystem    = fileSystem;
            _imageService  = imageService;

            this.Icon = BitmapFrame.Create(_imageService.ToolbarIconUri);

            CheckOperatingSystemCompatibility();

            // Certain things like Cef (our markdown browser engine) get unhappy when GUI is started from a different cwd.
            // If we're in a different one, reset it to our app files directory.
            if (_fileSystem.get_directory_name(Environment.CurrentDirectory) != Bootstrapper.ApplicationFilesPath)
            {
                Environment.CurrentDirectory = Bootstrapper.ApplicationFilesPath;
            }
        }
        public virtual void run(ChocolateyConfiguration configuration)
        {
            this.Log().Info("{0} is unpacking required files for use. Overwriting? {1}".format_with(ApplicationParameters.Name, configuration.Force));
            // refactor - thank goodness this is temporary, cuz manifest resource streams are dumb

            // unpack the manifest file as well
            AssemblyFileExtractor.extract_all_resources_to_relative_directory(_fileSystem, Assembly.GetAssembly(typeof(ChocolateyUnpackSelfCommand)), _fileSystem.get_directory_name(_fileSystem.get_current_assembly_path()), new List <string>(), "chocolatey.console");

            IList <string> folders = new List <string>
            {
                "helpers",
                "functions",
                "redirects",
                "tools"
            };

            AssemblyFileExtractor.extract_all_resources_to_relative_directory(
                _fileSystem,
                assembly,
                _fileSystem.get_directory_name(_fileSystem.get_current_assembly_path()),
                folders,
                ApplicationParameters.ChocolateyFileResources,
                overwriteExisting: configuration.Force,
                logOutput: true);
        }
Example #6
0
        public void serialize <XmlType>(XmlType xmlType, string xmlFilePath)
        {
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(xmlFilePath));

            var xmlUpdateFilePath = xmlFilePath + ".update";

            FaultTolerance.try_catch_with_logging_exception(
                () =>
            {
                var xmlSerializer = new XmlSerializer(typeof(XmlType));
                //var textWriter = new StreamWriter(xmlUpdateFilePath, append: false, encoding: new UTF8Encoding(encoderShouldEmitUTF8Identifier: false))
                var textWriter = new StreamWriter(xmlUpdateFilePath, append: false, encoding: new UTF8Encoding(encoderShouldEmitUTF8Identifier: true))
                {
                    AutoFlush = true
                };

                xmlSerializer.Serialize(textWriter, xmlType);
                textWriter.Flush();

                textWriter.Close();
                textWriter.Dispose();

                if (!_hashProvider.hash_file(xmlFilePath).is_equal_to(_hashProvider.hash_file(xmlUpdateFilePath)))
                {
                    _fileSystem.copy_file(xmlUpdateFilePath, xmlFilePath, overwriteExisting: true);
                }

                _fileSystem.delete_file(xmlUpdateFilePath);
            },
                "Error serializing type {0}".format_with(typeof(XmlType)),
                throwError: true);
        }
Example #7
0
        public static int execute(
            string command,
            IFileSystem fileSystem,
            int waitForExitSeconds,
            Action <object, DataReceivedEventArgs> stdOutAction,
            Action <object, DataReceivedEventArgs> stdErrAction
            )
        {
            if (string.IsNullOrWhiteSpace(_powershell))
            {
                _powershell = get_powershell_location(fileSystem);
            }
            //-NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%DIR%chocolatey.ps1' %PS_ARGS%"
            string arguments = "-NoProfile -NoLogo -ExecutionPolicy Bypass -Command \"{0}\"".format_with(command);

            return(CommandExecutor.execute(
                       _powershell,
                       arguments,
                       waitForExitSeconds,
                       workingDirectory: fileSystem.get_directory_name(Assembly.GetExecutingAssembly().Location),
                       stdOutAction: stdOutAction,
                       stdErrAction: stdErrAction,
                       updateProcessPath: true
                       ));
        }
 /// <summary>
 ///   Extract binary file from an assembly to a location on disk
 /// </summary>
 /// <param name="fileSystem">The file system.</param>
 /// <param name="assembly">The assembly.</param>
 /// <param name="manifestLocation">The manifest location.</param>
 /// <param name="filePath">The file path.</param>
 /// <param name="overwriteExisting">
 ///   if set to <c>true</c> [overwrite existing].
 /// </param>
 public static void extract_binary_file_from_assembly(IFileSystem fileSystem, IAssembly assembly, string manifestLocation, string filePath, bool overwriteExisting = false)
 {
     if (overwriteExisting || !fileSystem.file_exists(filePath))
     {
         fileSystem.create_directory_if_not_exists(fileSystem.get_directory_name(filePath));
         fileSystem.write_file(filePath, () => assembly.get_manifest_stream(manifestLocation));
     }
 }
Example #9
0
 /// <summary>
 ///   Extract binary file from an assembly to a location on disk
 /// </summary>
 /// <param name="fileSystem">The file system.</param>
 /// <param name="assembly">The assembly.</param>
 /// <param name="manifestLocation">The manifest location.</param>
 /// <param name="filePath">The file path.</param>
 /// <param name="overwriteExisting">
 ///   if set to <c>true</c> [overwrite existing].
 /// </param>
 public static void extract_binary_file_from_assembly(IFileSystem fileSystem, IAssembly assembly, string manifestLocation, string filePath, bool overwriteExisting = false)
 {
     if (overwriteExisting || !fileSystem.file_exists(filePath))
     {
         fileSystem.create_directory_if_not_exists(fileSystem.get_directory_name(filePath));
         fileSystem.write_file(filePath, () => assembly.get_manifest_stream(manifestLocation));
     }
 }
Example #10
0
        public void generate_file_from_template(ChocolateyConfiguration configuration, TemplateValues tokens, string template, string fileLocation, Encoding encoding)
        {
            template = TokenReplacer.replace_tokens(tokens, template);
            template = TokenReplacer.replace_tokens(tokens.AdditionalProperties, template);

            if (configuration.RegularOutput)
            {
                this.Log().Info(() => "Generating template to a file{0} at '{1}'".format_with(Environment.NewLine, fileLocation));
            }
            this.Log().Debug(() => "{0}".format_with(template));
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(fileLocation));
            _fileSystem.write_file(fileLocation, template, encoding);
        }
Example #11
0
        private void handle_message(PreRunMessage message)
        {
            this.Log().Debug(ChocolateyLoggers.Verbose, "[Pending] Removing all pending packages that should not be considered installed...");

            var pendingFiles = _fileSystem.get_files(ApplicationParameters.PackagesLocation, ApplicationParameters.PackagePendingFileName, SearchOption.AllDirectories).ToList();

            foreach (var pendingFile in pendingFiles.or_empty_list_if_null())
            {
                var packageFolder = _fileSystem.get_directory_name(pendingFile);
                this.Log().Warn("[Pending] Removing incomplete install for '{0}'".format_with(_fileSystem.get_directory_info_for(packageFolder).Name));

                FaultTolerance.retry(2, () => _fileSystem.delete_directory_if_exists(packageFolder, recursive: true, overrideAttributes: true, isSilent: true), 500, isSilent: true);
            }
        }
Example #12
0
        public void serialize <XmlType>(XmlType xmlType, string xmlFilePath, bool isSilent)
        {
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(xmlFilePath));

            FaultTolerance.try_catch_with_logging_exception(
                () =>
            {
                var xmlSerializer = new XmlSerializer(typeof(XmlType));

                // Write the updated file to memory
                using (var memoryStream = new MemoryStream())
                    using (var streamWriter = new StreamWriter(memoryStream, encoding: new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)))
                    {
                        xmlSerializer.Serialize(streamWriter, xmlType);
                        streamWriter.Flush();

                        memoryStream.Position = 0;

                        // Grab the hash of both files and compare them.
                        var originalFileHash = _hashProvider.hash_file(xmlFilePath);
                        if (!originalFileHash.is_equal_to(_hashProvider.hash_stream(memoryStream)))
                        {
                            // If there wasn't a file there in the first place, just write the new one out directly.
                            if (string.IsNullOrEmpty(originalFileHash))
                            {
                                using (var updateFileStream = _fileSystem.create_file(xmlFilePath))
                                {
                                    memoryStream.Position = 0;
                                    memoryStream.CopyTo(updateFileStream);

                                    return;
                                }
                            }

                            // Otherwise, create an update file, and resiliently move it into place.
                            var tempUpdateFile = xmlFilePath + ".update";
                            using (var updateFileStream = _fileSystem.create_file(tempUpdateFile))
                            {
                                memoryStream.Position = 0;
                                memoryStream.CopyTo(updateFileStream);
                            }
                            _fileSystem.replace_file(tempUpdateFile, xmlFilePath, xmlFilePath + ".backup");
                        }
                    }
            },
                "Error serializing type {0}".format_with(typeof(XmlType)),
                throwError: true,
                isSilent: isSilent);
        }
        /// <summary>
        ///   Extract text file from assembly to location on disk.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="manifestLocation">The manifest location.</param>
        /// <param name="filePath">The file path.</param>
        /// <param name="overwriteExisting">
        ///   if set to <c>true</c> [overwrite existing].
        /// </param>
        /// <exception cref="System.IO.FileNotFoundException"></exception>
        public static void extract_text_file_from_assembly(IFileSystem fileSystem, IAssembly assembly, string manifestLocation, string filePath, bool overwriteExisting = false)
        {
            if (overwriteExisting || !fileSystem.file_exists(filePath))
            {
                fileSystem.create_directory_if_not_exists(fileSystem.get_directory_name(filePath));
                var fileText = assembly.get_manifest_string(manifestLocation);
                if (string.IsNullOrWhiteSpace(fileText))
                {
                    string errorMessage = "Could not find a file in the manifest resource stream of '{0}' at '{1}'.".format_with(assembly.FullName, manifestLocation);
                    "chocolatey".Log().Error(() => errorMessage);
                    throw new FileNotFoundException(errorMessage);
                }

                fileSystem.write_file(filePath, fileText, Encoding.UTF8);
            }
        }
        /// <summary>
        ///   Extract text file from assembly to location on disk.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="manifestLocation">The manifest location.</param>
        /// <param name="filePath">The file path.</param>
        /// <param name="overwriteExisting">
        ///   if set to <c>true</c> [overwrite existing].
        /// </param>
        /// <exception cref="System.IO.FileNotFoundException"></exception>
        public static void extract_text_file_from_assembly(IFileSystem fileSystem, IAssembly assembly, string manifestLocation, string filePath, bool overwriteExisting = false)
        {
            if (overwriteExisting || !fileSystem.file_exists(filePath))
            {
                fileSystem.create_directory_if_not_exists(fileSystem.get_directory_name(filePath));
                var fileText = assembly.get_manifest_string(manifestLocation);
                if (string.IsNullOrWhiteSpace(fileText))
                {
                    string errorMessage = "Could not find a file in the manifest resource stream of '{0}' at '{1}'.".format_with(assembly.FullName, manifestLocation);
                    "chocolatey".Log().Error(() => errorMessage);
                    throw new FileNotFoundException(errorMessage);
                }

                fileSystem.write_file(filePath, fileText, Encoding.UTF8);
            }
        }
 /// <summary>
 ///   Extract binary file from an assembly to a location on disk
 /// </summary>
 /// <param name="fileSystem">The file system.</param>
 /// <param name="assembly">The assembly.</param>
 /// <param name="manifestLocation">The manifest location.</param>
 /// <param name="filePath">The file path.</param>
 /// <param name="overwriteExisting">
 ///   if set to <c>true</c> [overwrite existing].
 /// </param>
 /// <param name="throwEror">Throw an error if there are issues</param>
 public static void extract_binary_file_from_assembly(IFileSystem fileSystem, IAssembly assembly, string manifestLocation, string filePath, bool overwriteExisting = false, bool throwEror = true)
 {
     if (overwriteExisting || !fileSystem.file_exists(filePath))
     {
         FaultTolerance.try_catch_with_logging_exception(
             () =>
         {
             fileSystem.create_directory_if_not_exists(fileSystem.get_directory_name(filePath));
             fileSystem.write_file(filePath, () => assembly.get_manifest_stream(manifestLocation));
         },
             errorMessage: "Unable to extract binary",
             throwError: throwEror,
             logWarningInsteadOfError: false,
             logDebugInsteadOfError: !throwEror,
             isSilent: !throwEror);
     }
 }
Example #16
0
        private void handle_unsuccessful_install(PackageResult packageResult)
        {
            foreach (var message in packageResult.Messages.Where(m => m.MessageType == ResultType.Error))
            {
                this.Log().Error(message.Message);
            }

            _fileSystem.create_directory_if_not_exists(ApplicationParameters.PackageFailuresLocation);
            foreach (var file in _fileSystem.get_files(packageResult.InstallLocation, "*.*", SearchOption.AllDirectories))
            {
                var badFile = file.Replace(ApplicationParameters.PackagesLocation, ApplicationParameters.PackageFailuresLocation);
                _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(badFile));
                _fileSystem.move_file(file, badFile);
                //_fileSystem.copy_file_unsafe(file, badFile,overwriteTheExistingFile:true);
            }
            Thread.Sleep(2000); // sleep for enough time that the for half a second to allow the folder to be cleared
            _fileSystem.delete_directory(packageResult.InstallLocation, recursive: true);
        }
Example #17
0
        /// <summary>
        ///   Looks for file and generates a notification.
        /// </summary>
        public void look_for_file_and_generate_notification()
        {
            try
            {
                IList <string> filesToProcess = new List <string>();

                if (is_directory(FilePath))
                {
                    filesToProcess = _fileSystem.get_files(FilePath, "*.*", SearchOption.AllDirectories).ToList();
                }
                else if (_fileSystem.file_exists(FilePath))
                {
                    filesToProcess.Add(FilePath);
                }

                if (filesToProcess.Count != 0)
                {
                    foreach (string file in filesToProcess)
                    {
                        var tempFile = file;
                        if (_renameFile)
                        {
                            var renamedFile = string.Format(
                                "{0}_renamed{1}",
                                _fileSystem.get_file_name_without_extension(file),
                                _fileSystem.get_file_extension(file));
                            tempFile = _fileSystem.combine_paths(_fileSystem.get_directory_name(file), renamedFile);
                            _fileSystem.move_file(file, tempFile);
                        }

                        file_found_event.Invoke(new FileFoundEventArgs(tempFile));
                    }
                }
            }
            catch (Exception ex)
            {
                this.Log()
                .Error(
                    () =>
                    string.Format("Exception caught when watching for trigger files:{0}{1}", Environment.NewLine, ex));
            }
        }
        public void run(ChocolateyConfiguration configuration)
        {
            this.Log().Info("{0} is unpacking required files for use. Overwriting? {1}".format_with(ApplicationParameters.Name, configuration.Force));
            //refactor - thank goodness this is temporary, cuz manifest resource streams are dumb
            IList <string> folders = new List <string>
            {
                "helpers",
                "functions",
                "redirects",
                "tools"
            };

            AssemblyFileExtractor.extract_all_resources_to_relative_directory(
                _fileSystem,
                assembly,
                _fileSystem.get_directory_name(Assembly.GetExecutingAssembly().Location),
                folders,
                ApplicationParameters.ChocolateyFileResources,
                overwriteExisting: configuration.Force);
        }
Example #19
0
        public static int execute(
            string command,
            IFileSystem fileSystem,
            int waitForExitSeconds,
            Action<object, DataReceivedEventArgs> stdOutAction,
            Action<object, DataReceivedEventArgs> stdErrAction
            )
        {
            if (string.IsNullOrWhiteSpace(_powershell)) _powershell = get_powershell_location(fileSystem);
            //-NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%DIR%chocolatey.ps1' %PS_ARGS%"
            string arguments = "-NoProfile -NoLogo -ExecutionPolicy Bypass -Command \"{0}\"".format_with(command);

            return CommandExecutor.execute_static(
                _powershell,
                arguments,
                waitForExitSeconds,
                workingDirectory: fileSystem.get_directory_name(fileSystem.get_current_assembly_path()),
                stdOutAction: stdOutAction,
                stdErrAction: stdErrAction,
                updateProcessPath: true
                );
        }
Example #20
0
        public void serialize <XmlType>(XmlType xmlType, string xmlFilePath)
        {
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(xmlFilePath));

            FaultTolerance.try_catch_with_logging_exception(
                () =>
            {
                var xmlSerializer = new XmlSerializer(typeof(XmlType));
                var textWriter    = new StreamWriter(xmlFilePath, append: false, encoding: Encoding.UTF8)
                {
                    AutoFlush = true
                };

                xmlSerializer.Serialize(textWriter, xmlType);
                textWriter.Flush();

                textWriter.Close();
                textWriter.Dispose();
            },
                "Error serializing type {0}".format_with(typeof(XmlType)),
                throwError: true);
        }
Example #21
0
        public ShellView(
            IDialogService dialogService,
            IProgressService progressService,
            IChocolateyConfigurationProvider chocolateyConfigurationProvider,
            IConfigService configService,
            IFileSystem fileSystem,
            IImageService imageService)
        {
            InitializeComponent();

            dialogService.ShellView   = this;
            progressService.ShellView = this;

            _progressService = progressService;
            _chocolateyConfigurationProvider = chocolateyConfigurationProvider;
            _configService = configService;
            _fileSystem    = fileSystem;
            _imageService  = imageService;

            this.Icon = BitmapFrame.Create(_imageService.ToolbarIconUri);

            CheckOperatingSystemCompatibility();

            // Certain things like Cef (our markdown browser engine) get unhappy when GUI is started from a different cwd.
            // If we're in a different one, reset it to our app files directory.
            if (_fileSystem.get_directory_name(Environment.CurrentDirectory) != Bootstrapper.ApplicationFilesPath)
            {
                Environment.CurrentDirectory = Bootstrapper.ApplicationFilesPath;
            }

            dialogService.ChildWindowOpened += (sender, o) => IsAnyDialogOpen = true;
            dialogService.ChildWindowClosed += (sender, o) => IsAnyDialogOpen = false;

            SetLanguage(TranslationSource.Instance.CurrentCulture);

            TranslationSource.Instance.PropertyChanged += TranslationLanguageChanged;
        }
        public void run(PackageResult packageResult, ChocolateyConfiguration config)
        {
            if (!config.Features.AutoUninstaller)
            {
                this.Log().Info(" Skipping auto uninstaller - AutoUninstaller feature is not enabled.");
                return;
            }

            var pkgInfo = _packageInfoService.get_package_information(packageResult.Package);

            if (pkgInfo.RegistrySnapshot == null)
            {
                this.Log().Info(" Skipping auto uninstaller - No registry snapshot.");
                return;
            }

            var registryKeys = pkgInfo.RegistrySnapshot.RegistryKeys;

            if (registryKeys == null || registryKeys.Count == 0)
            {
                this.Log().Info(" Skipping auto uninstaller - No registry keys in snapshot.");
                return;
            }

            this.Log().Info(" Running auto uninstaller...");
            if (WaitForCleanup)
            {
                this.Log().Debug("Sleeping for {0} seconds to allow Windows to finish cleaning up.".format_with(SLEEP_TIME));
                Thread.Sleep((int)TimeSpan.FromSeconds(SLEEP_TIME).TotalMilliseconds);
            }

            foreach (var key in registryKeys.or_empty_list_if_null())
            {
                this.Log().Debug(() => " Preparing uninstall key '{0}'".format_with(key.UninstallString));

                if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))
                {
                    this.Log().Info(" Skipping auto uninstaller - The application appears to have been uninstalled already by other means.");
                    this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation)));
                    this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)));
                    continue;
                }

                // split on " /" and " -" for quite a bit more accuracy
                IList <string> uninstallArgsSplit = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                var            uninstallExe       = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault();
                var            uninstallArgs      = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty);
                uninstallExe = uninstallExe.remove_surrounding_quotes();
                this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));


                IInstaller installer = new CustomInstaller();

                switch (key.InstallerType)
                {
                case InstallerType.Msi:
                    installer = new MsiInstaller();
                    break;

                case InstallerType.InnoSetup:
                    installer = new InnoSetupInstaller();
                    break;

                case InstallerType.Nsis:
                    installer = new NsisInstaller();
                    break;

                case InstallerType.InstallShield:
                    installer = new InstallShieldInstaller();
                    break;
                }

                this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name));

                if (key.InstallerType == InstallerType.Msi)
                {
                    // because sometimes the key is set with /i to allow for modify :/
                    uninstallArgs = uninstallArgs.Replace("/I{", "/X{");
                    uninstallArgs = uninstallArgs.Replace("/i{", "/X{");
                    uninstallArgs = uninstallArgs.Replace("/I ", "/X ");
                    uninstallArgs = uninstallArgs.Replace("/i ", "/X ");
                }

                if (!key.HasQuietUninstall)
                {
                    //todo: ultimately we should merge keys
                    uninstallArgs += " " + installer.build_uninstall_command_arguments();
                }

                var logLocation = _fileSystem.combine_paths(_fileSystem.get_full_path(config.CacheLocation), "chocolatey", pkgInfo.Package.Id, pkgInfo.Package.Version.to_string());
                _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(logLocation));
                uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, logLocation);

                this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs));

                if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller))
                {
                    var skipUninstaller = true;
                    if (config.PromptForConfirmation)
                    {
                        var selection = InteractivePrompt.prompt_for_confirmation("Uninstall may not be silent (could not detect). Proceed?", new[] { "yes", "no" }, defaultChoice: null, requireAnswer: true);
                        if (selection.is_equal_to("no"))
                        {
                            skipUninstaller = false;
                        }
                    }

                    if (skipUninstaller)
                    {
                        this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists.");
                        return;
                    }
                }

                var exitCode = _commandExecutor.execute(
                    uninstallExe,
                    uninstallArgs.trim_safe(),
                    config.CommandExecutionTimeoutSeconds,
                    (s, e) =>
                {
                    if (e == null || string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Info(() => " [AutoUninstaller] {0}".format_with(e.Data));
                },
                    (s, e) =>
                {
                    if (e == null || string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data));
                },
                    updateProcessPath: false);

                if (!installer.ValidUninstallExitCodes.Contains(exitCode))
                {
                    Environment.ExitCode = exitCode;
                    string logMessage = " Auto uninstaller failed. Please remove machine installation manually.{0} Exit code was {1}".format_with(Environment.NewLine, exitCode);
                    this.Log().Error(() => logMessage);
                    packageResult.Messages.Add(new ResultMessage(config.Features.FailOnAutoUninstaller ? ResultType.Error : ResultType.Warn, logMessage));
                }
                else
                {
                    this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} or detected previous uninstall.".format_with(packageResult.Package.Id));
                }
            }
        }
Example #23
0
        public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, PackageResult packageResult, string packageCacheLocation)
        {
            var userProvidedUninstallArguments = string.Empty;
            var userOverrideUninstallArguments = false;
            var package = packageResult.Package;

            if (package != null)
            {
                if (!PackageUtility.package_is_a_dependency(config, package.Id) || config.ApplyInstallArgumentsToDependencies)
                {
                    userProvidedUninstallArguments = config.InstallArguments;
                    userOverrideUninstallArguments = config.OverrideArguments;

                    if (!string.IsNullOrWhiteSpace(userProvidedUninstallArguments))
                    {
                        this.Log().Debug(ChocolateyLoggers.Verbose, " Using user passed {2}uninstaller args for {0}:'{1}'".format_with(package.Id, userProvidedUninstallArguments.escape_curly_braces(), userOverrideUninstallArguments ? "overriding " : string.Empty));
                    }
                }
            }

            //todo: if there is a local package, look to use it in the future
            if (string.IsNullOrWhiteSpace(key.UninstallString))
            {
                this.Log().Info(" Skipping auto uninstaller - '{0}' does not have an uninstall string.".format_with(!string.IsNullOrEmpty(key.DisplayName.to_string()) ? key.DisplayName.to_string().escape_curly_braces() : "The application"));
                return;
            }

            this.Log().Debug(() => " Preparing uninstall key '{0}' for '{1}'".format_with(key.UninstallString.to_string().escape_curly_braces(), key.DisplayName.to_string().escape_curly_braces()));

            if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))
            {
                this.Log().Info(" Skipping auto uninstaller - '{0}' appears to have been uninstalled already by other means.".format_with(!string.IsNullOrEmpty(key.DisplayName.to_string()) ? key.DisplayName.to_string().escape_curly_braces() : "The application"));
                this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.to_string().escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation)));
                this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)));
                return;
            }

            // split on " /" and " -" for quite a bit more accuracy
            IList <string> uninstallArgsSplit = key.UninstallString.to_string().Replace("&quot;", "\"").Replace("&apos;", "'").Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            var            uninstallExe       = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault().trim_safe();

            if (uninstallExe.Count(u => u == '"') > 2)
            {
                uninstallExe = uninstallExe.Split(new [] { " \"" }, StringSplitOptions.RemoveEmptyEntries).First();
            }

            if (uninstallExe.Count(u => u == ':') > 1)
            {
                try
                {
                    var firstMatch = Regex.Match(uninstallExe, @"\s+\w\:", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                    uninstallExe = uninstallExe.Substring(0, firstMatch.Index);
                }
                catch (Exception ex)
                {
                    this.Log().Debug("Error splitting the uninstall string:{0} {1}".format_with(Environment.NewLine, ex.to_string()));
                }
            }
            var uninstallArgs = key.UninstallString.to_string().Replace("&quot;", "\"").Replace("&apos;", "'").Replace(uninstallExe.to_string(), string.Empty).trim_safe();

            uninstallExe = uninstallExe.remove_surrounding_quotes();
            this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));

            if (uninstallExe.contains("\\") || uninstallExe.contains("/"))
            {
                if (!_fileSystem.file_exists(uninstallExe))
                {
                    this.Log().Info(" Skipping auto uninstaller - The uninstaller file no longer exists. \"{0}\"".format_with(uninstallExe));
                    return;
                }
            }

            IInstaller installer = get_installer_type(key, uninstallExe, uninstallArgs);

            this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name));

            if (key.InstallerType == InstallerType.Msi)
            {
                // because sometimes the key is set with /i to allow for modify :/
                uninstallArgs = uninstallArgs.Replace("/I{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/i{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/I ", "/X ");
                uninstallArgs = uninstallArgs.Replace("/i ", "/X ");
            }

            if (!key.HasQuietUninstall)
            {
                //todo: ultimately we should merge keys
                uninstallArgs += " " + installer.build_uninstall_command_arguments();
            }

            if (!string.IsNullOrWhiteSpace(userProvidedUninstallArguments))
            {
                if (userOverrideUninstallArguments)
                {
                    this.Log().Debug(() => " Replacing original uninstall arguments of '{0}' with '{1}'".format_with(uninstallArgs.escape_curly_braces(), userProvidedUninstallArguments.escape_curly_braces()));
                    uninstallArgs = userProvidedUninstallArguments;
                }
                else
                {
                    this.Log().Debug(() => " Appending original uninstall arguments with '{0}'".format_with(userProvidedUninstallArguments.escape_curly_braces()));
                    uninstallArgs += " " + userProvidedUninstallArguments;
                }
            }

            this.Log().Debug(() => " Setting up uninstall logging directory at {0}".format_with(packageCacheLocation.escape_curly_braces()));
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(packageCacheLocation));
            uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, packageCacheLocation);
            uninstallArgs = uninstallArgs.Replace(InstallTokens.TEMP_LOCATION, packageCacheLocation);

            this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs.escape_curly_braces()));

            if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller))
            {
                var skipUninstaller = true;

                var timeout = config.PromptForConfirmation ? 0 : 30;

                var selection = InteractivePrompt.prompt_for_confirmation(
                    "Uninstall may not be silent (could not detect). Proceed?",
                    new[] { "yes", "no" },
                    defaultChoice: "no",
                    requireAnswer: true,
                    allowShortAnswer: true,
                    shortPrompt: true,
                    timeoutInSeconds: timeout
                    );
                if (selection.is_equal_to("yes"))
                {
                    skipUninstaller = false;
                }

                if (skipUninstaller)
                {
                    this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists.");
                    this.Log().Warn("If the application was not removed with a chocolateyUninstall.ps1,{0} please remove it from Programs and Features manually.".format_with(Environment.NewLine));
                    return;
                }
            }

            var exitCode = _commandExecutor.execute(
                uninstallExe,
                uninstallArgs.trim_safe(),
                config.CommandExecutionTimeoutSeconds,
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Info(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                updateProcessPath: false);

            if (!installer.ValidUninstallExitCodes.Contains(exitCode))
            {
                Environment.ExitCode = exitCode;
                string logMessage = " Auto uninstaller failed. Please remove machine installation manually.{0} Exit code was {1}".format_with(Environment.NewLine, exitCode);
                this.Log().Error(() => logMessage.escape_curly_braces());
                packageResult.Messages.Add(new ResultMessage(config.Features.FailOnAutoUninstaller ? ResultType.Error : ResultType.Warn, logMessage));
            }
            else
            {
                this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} or detected previous uninstall.".format_with(packageResult.Package.Id));
            }
        }
        public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, PackageResult packageResult, string packageCacheLocation)
        {
            this.Log().Debug(() => " Preparing uninstall key '{0}'".format_with(key.UninstallString.to_string().escape_curly_braces()));

            if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))
            {
                this.Log().Info(" Skipping auto uninstaller - The application appears to have been uninstalled already by other means.");
                this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.to_string().escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation)));
                this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)));
                return;
            }

            // split on " /" and " -" for quite a bit more accuracy
            IList <string> uninstallArgsSplit = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            var            uninstallExe       = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault();

            if (uninstallExe.Count(u => u == '"') > 2)
            {
                uninstallExe = uninstallExe.Split(new [] { " \"" }, StringSplitOptions.RemoveEmptyEntries).First();
            }
            var uninstallArgs = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty);

            uninstallExe = uninstallExe.remove_surrounding_quotes();
            this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));

            if (uninstallExe.contains("\\") || uninstallExe.contains("/"))
            {
                if (!_fileSystem.file_exists(uninstallExe))
                {
                    this.Log().Info(" Skipping auto uninstaller - The uninstaller file no longer exists. \"{0}\"".format_with(uninstallExe));
                    return;
                }
            }

            IInstaller installer = get_installer_type(key, uninstallExe, uninstallArgs);

            this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name));

            if (key.InstallerType == InstallerType.Msi)
            {
                // because sometimes the key is set with /i to allow for modify :/
                uninstallArgs = uninstallArgs.Replace("/I{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/i{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/I ", "/X ");
                uninstallArgs = uninstallArgs.Replace("/i ", "/X ");
            }

            if (!key.HasQuietUninstall)
            {
                //todo: ultimately we should merge keys
                uninstallArgs += " " + installer.build_uninstall_command_arguments();
            }

            this.Log().Debug(() => " Setting up uninstall logging directory at {0}".format_with(packageCacheLocation.escape_curly_braces()));
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(packageCacheLocation));
            uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, packageCacheLocation);
            uninstallArgs = uninstallArgs.Replace(InstallTokens.TEMP_LOCATION, packageCacheLocation);

            this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs.escape_curly_braces()));

            if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller))
            {
                if (!config.Information.IsLicensedVersion)
                {
                    this.Log().Warn(@"
  Did you know licensed versions of Chocolatey are 95% effective with 
   Automatic Uninstaller due to licensed enhancements and Package 
   Synchronizer?
");
                }

                var skipUninstaller = true;

                var timeout = config.PromptForConfirmation ? 0 : 30;

                var selection = InteractivePrompt.prompt_for_confirmation(
                    "Uninstall may not be silent (could not detect). Proceed?",
                    new[] { "yes", "no" },
                    defaultChoice: "no",
                    requireAnswer: true,
                    allowShortAnswer: true,
                    shortPrompt: true,
                    timeoutInSeconds: timeout
                    );
                if (selection.is_equal_to("yes"))
                {
                    skipUninstaller = false;
                }

                if (skipUninstaller)
                {
                    this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists.");
                    this.Log().Warn("If the application was not removed with a chocolateyUninstall.ps1,{0} please remove it from Programs and Features manually.".format_with(Environment.NewLine));
                    return;
                }
            }

            var exitCode = _commandExecutor.execute(
                uninstallExe,
                uninstallArgs.trim_safe(),
                config.CommandExecutionTimeoutSeconds,
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Info(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                updateProcessPath: false);

            if (!installer.ValidUninstallExitCodes.Contains(exitCode))
            {
                Environment.ExitCode = exitCode;
                string logMessage = " Auto uninstaller failed. Please remove machine installation manually.{0} Exit code was {1}".format_with(Environment.NewLine, exitCode);
                this.Log().Error(() => logMessage.escape_curly_braces());
                packageResult.Messages.Add(new ResultMessage(config.Features.FailOnAutoUninstaller ? ResultType.Error : ResultType.Warn, logMessage));
            }
            else
            {
                this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} or detected previous uninstall.".format_with(packageResult.Package.Id));
            }
        }
Example #25
0
        public XmlType deserialize <XmlType>(string xmlFilePath, int retryCount)
        {
            return(FaultTolerance.retry(retryCount, () => GlobalMutex.enter(
                                            () =>
            {
                this.Log().Trace("Entered mutex to deserialize '{0}'".format_with(xmlFilePath));

                return FaultTolerance.try_catch_with_logging_exception(
                    () =>
                {
                    var xmlSerializer = new XmlSerializer(typeof(XmlType));
                    using (var fileStream = _fileSystem.open_file_readonly(xmlFilePath))
                        using (var fileReader = new StreamReader(fileStream))
                            using (var xmlReader = XmlReader.Create(fileReader))
                            {
                                if (!xmlSerializer.CanDeserialize(xmlReader))
                                {
                                    this.Log().Warn("Cannot deserialize response of type {0}", typeof(XmlType));
                                    return default(XmlType);
                                }

                                try
                                {
                                    return (XmlType)xmlSerializer.Deserialize(xmlReader);
                                }
                                catch (InvalidOperationException ex)
                                {
                                    // Check if its just a malformed document.
                                    if (ex.Message.Contains("There is an error in XML document"))
                                    {
                                        // If so, check for a backup file and try an parse that.
                                        if (_fileSystem.file_exists(xmlFilePath + ".backup"))
                                        {
                                            using (var backupStream = _fileSystem.open_file_readonly(xmlFilePath + ".backup"))
                                                using (var backupReader = new StreamReader(backupStream))
                                                    using (var backupXmlReader = XmlReader.Create(backupReader))
                                                    {
                                                        var validConfig = (XmlType)xmlSerializer.Deserialize(backupXmlReader);

                                                        // If there's no errors and it's valid, go ahead and replace the bad file with the backup.
                                                        if (validConfig != null)
                                                        {
                                                            // Close fileReader so that we can copy the file without it being locked.
                                                            fileReader.Close();
                                                            _fileSystem.copy_file(xmlFilePath + ".backup", xmlFilePath, overwriteExisting: true);
                                                        }

                                                        return validConfig;
                                                    }
                                        }
                                    }

                                    throw;
                                }
                                finally
                                {
                                    foreach (var updateFile in _fileSystem.get_files(_fileSystem.get_directory_name(xmlFilePath), "*.update").or_empty_list_if_null())
                                    {
                                        this.Log().Debug("Removing '{0}'".format_with(updateFile));
                                        FaultTolerance.try_catch_with_logging_exception(
                                            () => _fileSystem.delete_file(updateFile),
                                            errorMessage: "Unable to remove update file",
                                            logDebugInsteadOfError: true,
                                            isSilent: true
                                            );
                                    }
                                }
                            }
                },
                    "Error deserializing response of type {0}".format_with(typeof(XmlType)),
                    throwError: true);
            }, MUTEX_TIMEOUT),
                                        waitDurationMilliseconds: 200,
                                        increaseRetryByMilliseconds: 200));
        }
        private void test_package(VerifyPackageMessage message)
        {
            //var lockTaken = TransactionLock.acquire(VAGRANT_LOCK_NAME, 7200);
            //if (!lockTaken)
            //{
            //    Bootstrap.handle_exception(new ApplicationException("Testing package {0} v{1} timed out waiting on transaction lock to open".format_with(message.PackageId, message.PackageVersion)));
            //    return;
            //}

            try
            {
                this.Log().Info(() => "========== {0} v{1} ==========".format_with(message.PackageId, message.PackageVersion));
                this.Log().Info(() => "Testing Package: {0} Version: {1}".format_with(message.PackageId, message.PackageVersion));

                _fileSystem.delete_file(".\\choco_logs\\chocolatey.log");
                var prepSuccess  = _testService.prep();
                var resetSuccess = _testService.reset();
                if (!prepSuccess || !resetSuccess)
                {
                    Bootstrap.handle_exception(new ApplicationException("Unable to test package due to testing service issues. See log for details"));
                    return;
                }

                if (_fileSystem.file_exists(_configuration.VboxIdPath))
                {
                    _vmId          = _fileSystem.read_file(_configuration.VboxIdPath);
                    _vmIdAvailable = !string.IsNullOrWhiteSpace(_vmId);
                }

                var tempFolder = Environment.GetEnvironmentVariable("TEMP");
                if (_vmIdAvailable && !tempFolder.EndsWith(_vmId))
                {
                    var runFolder = "{0}\\{1}".format_with(tempFolder, _vmId);
                    this.Log().Info(() => "Setting temp folder to: {0}".format_with(runFolder));

                    Environment.SetEnvironmentVariable("TEMP", runFolder);
                    _fileSystem.create_directory_if_not_exists(runFolder);
                }

                this.Log().Info(() => "Checking install.");

                const string imageDirectory = ".\\images";
                _fileSystem.create_directory_if_not_exists(imageDirectory);
                var installImage = string.Empty;

                var installResults = _testService.run(
                    "choco.exe install {0} --version {1} -fdvy --execution-timeout={2} --allow-downgrade".format_with(
                        message.PackageId,
                        message.PackageVersion,
                        _configuration.CommandExecutionTimeoutSeconds),
                    () =>
                {
                    this.Log().Info(() => "Timeout triggered.");
                    if (string.IsNullOrWhiteSpace(_vboxManageExe) || string.IsNullOrWhiteSpace(_configuration.VboxIdPath))
                    {
                        return;
                    }
                    if (!_vmIdAvailable)
                    {
                        return;
                    }

                    var imageLocation = _fileSystem.combine_paths(imageDirectory, _imageFormat.format_with(
                                                                      message.PackageId,
                                                                      message.PackageVersion,
                                                                      DateTime.Now.ToString(_dateTimeFormat),
                                                                      "install"
                                                                      ));

                    try
                    {
                        CommandExecutor.execute_static(_vboxManageExe,
                                                       "controlvm {" + _vmId + "} screenshotpng " + imageLocation,
                                                       30,
                                                       _fileSystem.get_directory_name(Assembly.GetExecutingAssembly().Location),
                                                       (o, e) =>
                        {
                            if (e == null || string.IsNullOrWhiteSpace(e.Data))
                            {
                                return;
                            }
                            this.Log().Debug(() => " [VboxManage] {0}".format_with(e.Data));
                        },
                                                       (o, e) =>
                        {
                            if (e == null || string.IsNullOrWhiteSpace(e.Data))
                            {
                                return;
                            }
                            this.Log().Warn(() => " [VboxManage][Error] {0}".format_with(e.Data));
                        },
                                                       null,
                                                       updateProcessPath: false,
                                                       allowUseWindow: false);

                        if (_fileSystem.file_exists(imageLocation))
                        {
                            installImage = _imageUploadService.upload_image(imageLocation);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.Log().Warn("Image capture failed for {0}v{1}:{2} {3}".format_with(message.PackageId, message.PackageVersion, Environment.NewLine, ex.Message));
                    }
                });

                installResults.ImageLink = installImage;

                if (had_environment_errors(installResults))
                {
                    return;
                }

                this.Log().Debug(() => "Grabbing actual log file to include in report.");
                var installLog     = string.Empty;
                var installLogFile = ".\\choco_logs\\chocolatey.log";
                try
                {
                    if (_fileSystem.file_exists(installLogFile))
                    {
                        installLog = _fileSystem.read_file(installLogFile);
                        _fileSystem.delete_file(installLogFile);
                    }
                }
                catch (Exception ex)
                {
                    Bootstrap.handle_exception(new ApplicationException("Unable to read file '{0}':{1} {2}".format_with(installLogFile, Environment.NewLine, ex.ToString()), ex));
                }

                this.Log().Debug(() => "Grabbing results files (.registry/.files) to include in report.");
                var registrySnapshot     = string.Empty;
                var registrySnapshotFile = ".\\files\\{0}.{1}\\.registry".format_with(message.PackageId, message.PackageVersion);
                try
                {
                    if (_fileSystem.file_exists(registrySnapshotFile))
                    {
                        registrySnapshot = _fileSystem.read_file(registrySnapshotFile);
                    }
                }
                catch (Exception ex)
                {
                    Bootstrap.handle_exception(new ApplicationException("Unable to read file '{0}':{1} {2}".format_with(registrySnapshotFile, Environment.NewLine, ex.ToString()), ex));
                }

                var filesSnapshot     = string.Empty;
                var filesSnapshotFile = ".\\files\\{0}.{1}\\.files".format_with(message.PackageId, message.PackageVersion);
                try
                {
                    if (_fileSystem.file_exists(filesSnapshotFile))
                    {
                        filesSnapshot = _fileSystem.read_file(filesSnapshotFile);
                    }
                }
                catch (Exception ex)
                {
                    Bootstrap.handle_exception(new ApplicationException("Unable to read file '{0}':{1} {2}".format_with(filesSnapshotFile, Environment.NewLine, ex.ToString()), ex));
                }

                var success = installResults.Success && installResults.ExitCode == 0;
                this.Log().Info(() => "Install was '{0}'.".format_with(success ? "successful" : "not successful"));

                if (detect_vagrant_errors(installResults.Logs, message.PackageId, message.PackageVersion))
                {
                    return;
                }

                var upgradeResults = new TestCommandOutputResult();

                var uninstallLog     = string.Empty;
                var uninstallResults = new TestCommandOutputResult();
                if (success)
                {
                    this.Log().Info(() => "Now checking uninstall.");

                    var uninstallImage = string.Empty;

                    uninstallResults = _testService.run("choco.exe uninstall {0} --version {1} -dvy --execution-timeout={2}".format_with(message.PackageId, message.PackageVersion, _configuration.CommandExecutionTimeoutSeconds),
                                                        () =>
                    {
                        if (string.IsNullOrWhiteSpace(_vboxManageExe) || string.IsNullOrWhiteSpace(_configuration.VboxIdPath))
                        {
                            return;
                        }
                        if (!_fileSystem.file_exists(_configuration.VboxIdPath))
                        {
                            return;
                        }
                        if (!_vmIdAvailable)
                        {
                            return;
                        }

                        var imageLocation = _fileSystem.combine_paths(imageDirectory, _imageFormat.format_with(
                                                                          message.PackageId,
                                                                          message.PackageVersion,
                                                                          DateTime.Now.ToString(_dateTimeFormat),
                                                                          "uninstall"
                                                                          ));

                        try
                        {
                            CommandExecutor.execute_static(_vboxManageExe,
                                                           "controlvm {" + _vmId + "} screenshotpng " + imageLocation,
                                                           30,
                                                           _fileSystem.get_directory_name(Assembly.GetExecutingAssembly().Location),
                                                           (o, e) =>
                            {
                                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                                {
                                    return;
                                }
                                this.Log().Debug(() => " [VboxManage] {0}".format_with(e.Data));
                            },
                                                           (o, e) =>
                            {
                                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                                {
                                    return;
                                }
                                this.Log().Warn(() => " [VboxManage][Error] {0}".format_with(e.Data));
                            },
                                                           null,
                                                           updateProcessPath: false,
                                                           allowUseWindow: false);

                            if (_fileSystem.file_exists(imageLocation))
                            {
                                uninstallImage = _imageUploadService.upload_image(imageLocation);
                            }
                        }
                        catch (Exception ex)
                        {
                            this.Log().Warn("Image capture failed for {0}v{1}:{2} {3}".format_with(message.PackageId, message.PackageVersion, Environment.NewLine, ex.Message));
                        }
                    });
                    this.Log().Info(() => "Uninstall was '{0}'.".format_with(uninstallResults.ExitCode == 0 ? "successful" : "not successful"));
                    this.Log().Debug(() => "Grabbing actual log file to include in report.");

                    uninstallResults.ImageLink = uninstallImage;

                    var uninstallLogFile = ".\\choco_logs\\chocolatey.log";
                    try
                    {
                        if (_fileSystem.file_exists(uninstallLogFile))
                        {
                            uninstallLog = _fileSystem.read_file(uninstallLogFile);
                            _fileSystem.delete_file(uninstallLogFile);
                        }
                    }
                    catch (Exception ex)
                    {
                        Bootstrap.handle_exception(new ApplicationException("Unable to read file '{0}':{1} {2}".format_with(uninstallLogFile, Environment.NewLine, ex.ToString()), ex));
                    }

                    if (had_environment_errors(uninstallResults))
                    {
                        return;
                    }
                    if (detect_vagrant_errors(uninstallResults.Logs, message.PackageId, message.PackageVersion))
                    {
                        return;
                    }
                }

                foreach (var subDirectory in _fileSystem.get_directories(".\\files").or_empty_list_if_null())
                {
                    try
                    {
                        _fileSystem.delete_directory_if_exists(subDirectory, recursive: true);
                    }
                    catch (Exception ex)
                    {
                        Bootstrap.handle_exception(new ApplicationException("Unable to cleanup files directory (where .chocolatey files are put):{0} {1}".format_with(Environment.NewLine, ex.ToString()), ex));
                    }
                }

                var logs = new List <PackageTestLog>();

                var summary = new StringBuilder();
                summary.AppendFormat("{0} v{1} - {2} - Package Test Results", message.PackageId, message.PackageVersion, success ? "Passed" : "Failed");
                summary.AppendFormat("{0} * [{1}packages/{2}/{3}]({1}packages/{2}/{3})", Environment.NewLine, _configuration.PackagesUrl.ensure_trailing_slash(), message.PackageId, message.PackageVersion);
                summary.AppendFormat("{0} * Tested {1} +00:00", Environment.NewLine, DateTime.UtcNow.ToString("dd MMM yyyy HH:mm:ss"));
                summary.AppendFormat("{0} * Tested against {1} ({2})", Environment.NewLine, "win2012r2x64", "Windows Server 2012 R2 x64");
                summary.AppendFormat("{0} * Tested with the latest version of choco, possibly a beta version.", Environment.NewLine);
                summary.AppendFormat(
                    "{0} * Tested with {1} service v{2}{3}",
                    Environment.NewLine,
                    ApplicationParameters.Name,
                    ApplicationParameters.ProductVersion,
                    string.IsNullOrWhiteSpace(_configuration.InstanceName) ? string.Empty : " (Instance: {0})".format_with(_configuration.InstanceName)
                    );
                summary.AppendFormat(
                    "{0} * Install {1}.",
                    Environment.NewLine,
                    installResults.ExitCode == 0
                        ? "was successful"
                        : "failed. Note that the process may have hung, indicating a not completely silent install. This is usually seen when the last entry in the log is calling the install. This can also happen when a window pops up and needs to be closed to continue");
                if (!string.IsNullOrWhiteSpace(upgradeResults.Logs))
                {
                    summary.AppendFormat(
                        "{0} * Upgrade {1}.",
                        Environment.NewLine,
                        upgradeResults.ExitCode == 0
                            ? "was successful"
                            : "failed. Note that the process may have hung, indicating a not completely silent install. This is usually seen when the last entry in the log is calling the install. This can also happen when a window pops up and needs to be closed to continue");
                }
                if (!string.IsNullOrWhiteSpace(uninstallResults.Logs))
                {
                    summary.AppendFormat(
                        "{0} * Uninstall {1}.",
                        Environment.NewLine,
                        uninstallResults.ExitCode == 0
                            ? "was successful"
                            : "failed (allowed). Note that the process may have hung, indicating a not completely silent uninstall. This is usually seen when the last entry in the log is calling the uninstall. This can also happen when a window pops up and needs to be closed to continue");
                }

                logs.Add(new PackageTestLog("_Summary.md", summary.ToString()));
                if (!string.IsNullOrWhiteSpace(installResults.Logs))
                {
                    logs.Add(new PackageTestLog("Install.txt", string.IsNullOrWhiteSpace(installLog) ? installResults.Logs : installLog));
                }
                if (!string.IsNullOrWhiteSpace(installResults.ImageLink))
                {
                    logs.Add(new PackageTestLog("InstallImage.md", @"
This is the image that was taken when the install test failed:

![{0} v{1} install failure]({2})
".format_with(message.PackageId, message.PackageVersion, installResults.ImageLink)));
                }

                if (!string.IsNullOrWhiteSpace(registrySnapshot))
                {
                    logs.Add(new PackageTestLog("1.RegistrySnapshot.xml", registrySnapshot));
                }
                if (!string.IsNullOrWhiteSpace(filesSnapshot))
                {
                    logs.Add(new PackageTestLog("FilesSnapshot.xml", filesSnapshot));
                }
                if (!string.IsNullOrWhiteSpace(upgradeResults.Logs))
                {
                    logs.Add(new PackageTestLog("Upgrade.txt", upgradeResults.Logs));
                }
                if (!string.IsNullOrWhiteSpace(uninstallResults.Logs))
                {
                    logs.Add(new PackageTestLog("Uninstall.txt", string.IsNullOrWhiteSpace(uninstallLog) ? uninstallResults.Logs : uninstallLog));
                }
                if (!string.IsNullOrWhiteSpace(uninstallResults.ImageLink))
                {
                    logs.Add(new PackageTestLog("UninstallImage.md", @"
This is the image that was taken when the uninstall test failed:

![{0} v{1} uninstall failure]({2})
".format_with(message.PackageId, message.PackageVersion, uninstallResults.ImageLink)));
                }

                EventManager.publish(
                    new PackageTestResultMessage(
                        message.PackageId,
                        message.PackageVersion,
                        "Windows2012R2 x64",
                        "win2012r2x64",
                        DateTime.UtcNow,
                        logs,
                        success: success
                        ));
            }
            catch (Exception ex)
            {
                Bootstrap.handle_exception(ex);
            }
            //finally
            //{
            //    TransactionLock.release(VAGRANT_LOCK_NAME, lockTaken: true);
            //}
        }