public static void extract_all_resources_to_relative_directory(IFileSystem fileSystem, IAssembly assembly, string directoryPath, IList<string> relativeDirectories, string resourcesToInclude, bool overwriteExisting = false, bool logOutput = false) { var resourceString = new StringBuilder(); foreach (var resourceName in assembly.GetManifestResourceNames()) { if (!resourceName.StartsWith(resourcesToInclude)) { continue; } resourceString.Clear(); resourceString.Append(resourceName); //var fileExtensionLocation = resourceName.LastIndexOf('.'); //resourceString.Remove(fileExtensionLocation, resourceString.Length - fileExtensionLocation); resourceString.Replace(resourcesToInclude + ".", ""); foreach (var directory in relativeDirectories) { resourceString.Replace("{0}".format_with(directory), "{0}{1}".format_with(directory, fileSystem.get_path_directory_separator_char())); } // replacing \. with \ resourceString.Replace("{0}.".format_with(fileSystem.get_path_directory_separator_char()), "{0}".format_with(fileSystem.get_path_directory_separator_char())); var fileLocation = resourceString.ToString(); //var fileLocation = fileSystem.combine_paths("", resourceString.ToString().Split('.')) + resourceName.Substring(fileExtensionLocation); var filePath = fileSystem.combine_paths(directoryPath, fileLocation); if (logOutput) "chocolatey".Log().Debug("Unpacking {0} to '{1}'".format_with(fileLocation,filePath)); extract_binary_file_from_assembly(fileSystem, assembly, resourceName, filePath, overwriteExisting); } }
private static void set_config_items(ChocolateyConfiguration config, ConfigFileSettings configFileSettings, IFileSystem fileSystem) { var cacheLocation = set_config_item(ApplicationParameters.ConfigSettings.CacheLocation, configFileSettings, string.IsNullOrWhiteSpace(configFileSettings.CacheLocation) ? string.Empty : configFileSettings.CacheLocation, "Cache location if not TEMP folder."); config.CacheLocation = !string.IsNullOrWhiteSpace(cacheLocation) ? cacheLocation : fileSystem.combine_paths(fileSystem.get_temp_path(), "chocolatey"); // System.Environment.GetEnvironmentVariable("TEMP"); if (string.IsNullOrWhiteSpace(config.CacheLocation)) { config.CacheLocation = fileSystem.combine_paths(ApplicationParameters.InstallLocation, "temp"); } var originalCommandTimeout = configFileSettings.CommandExecutionTimeoutSeconds; var commandExecutionTimeoutSeconds = -1; int.TryParse( set_config_item( ApplicationParameters.ConfigSettings.CommandExecutionTimeoutSeconds, configFileSettings, originalCommandTimeout == 0 ? ApplicationParameters.DefaultWaitForExitInSeconds.to_string() : originalCommandTimeout.to_string(), "Default timeout for command execution."), out commandExecutionTimeoutSeconds); config.CommandExecutionTimeoutSeconds = commandExecutionTimeoutSeconds; if (configFileSettings.CommandExecutionTimeoutSeconds <= 0) { set_config_item(ApplicationParameters.ConfigSettings.CommandExecutionTimeoutSeconds, configFileSettings, ApplicationParameters.DefaultWaitForExitInSeconds.to_string(), "Default timeout for command execution.", forceSettingValue: true); config.CommandExecutionTimeoutSeconds = ApplicationParameters.DefaultWaitForExitInSeconds; } config.ContainsLegacyPackageInstalls = set_config_item(ApplicationParameters.ConfigSettings.ContainsLegacyPackageInstalls, configFileSettings, "true", "Install has packages installed prior to 0.9.9 series.").is_equal_to(bool.TrueString); config.Proxy.Location = set_config_item(ApplicationParameters.ConfigSettings.Proxy, configFileSettings, string.Empty, "Explicit proxy location."); config.Proxy.User = set_config_item(ApplicationParameters.ConfigSettings.ProxyUser, configFileSettings, string.Empty, "Optional proxy user."); config.Proxy.EncryptedPassword = set_config_item(ApplicationParameters.ConfigSettings.ProxyPassword, configFileSettings, string.Empty, "Optional proxy password. Encrypted."); int minPositives=0; int.TryParse(set_config_item(ApplicationParameters.ConfigSettings.VirusCheckMinimumPositives, configFileSettings, "5", "Optional proxy password. Encrypted."), out minPositives); config.VirusCheckMinimumPositives = minPositives == 0 ? 5 : minPositives; }
private static void set_file_configuration(ChocolateyConfiguration config, IFileSystem fileSystem, IXmlService xmlService, Action<string> notifyWarnLoggingAction) { var globalConfigPath = ApplicationParameters.GlobalConfigFileLocation; AssemblyFileExtractor.extract_text_file_from_assembly(fileSystem, Assembly.GetExecutingAssembly(), ApplicationParameters.ChocolateyConfigFileResource, globalConfigPath); var configFileSettings = xmlService.deserialize<ConfigFileSettings>(globalConfigPath); var sources = new StringBuilder(); foreach (var source in configFileSettings.Sources.Where(s => !s.Disabled).or_empty_list_if_null()) { sources.AppendFormat("{0};", source.Value); } if (sources.Length != 0) { config.Sources = sources.Remove(sources.Length - 1, 1).ToString(); } set_machine_sources(config, configFileSettings); config.CacheLocation = !string.IsNullOrWhiteSpace(configFileSettings.CacheLocation) ? configFileSettings.CacheLocation : System.Environment.GetEnvironmentVariable("TEMP"); if (string.IsNullOrWhiteSpace(config.CacheLocation)) { config.CacheLocation = fileSystem.combine_paths(ApplicationParameters.InstallLocation, "temp"); } FaultTolerance.try_catch_with_logging_exception( () => fileSystem.create_directory_if_not_exists(config.CacheLocation), "Could not create temp directory at '{0}'".format_with(config.CacheLocation), logWarningInsteadOfError: true); config.ContainsLegacyPackageInstalls = configFileSettings.ContainsLegacyPackageInstalls; if (configFileSettings.CommandExecutionTimeoutSeconds <= 0) { configFileSettings.CommandExecutionTimeoutSeconds = ApplicationParameters.DefaultWaitForExitInSeconds; } config.CommandExecutionTimeoutSeconds = configFileSettings.CommandExecutionTimeoutSeconds; set_feature_flags(config, configFileSettings); // save so all updated configuration items get set to existing config FaultTolerance.try_catch_with_logging_exception( () => xmlService.serialize(configFileSettings, globalConfigPath), "Error updating '{0}'. Please ensure you have permissions to do so".format_with(globalConfigPath), logWarningInsteadOfError: true); }
private static void remove_old_chocolatey_exe(IFileSystem fileSystem) { try { fileSystem.delete_file(fileSystem.get_current_assembly_path() + ".old"); fileSystem.delete_file(fileSystem.combine_paths(AppDomain.CurrentDomain.BaseDirectory, "choco.exe.old")); } catch (Exception ex) { "chocolatey".Log().Warn("Attempting to delete choco.exe.old ran into an issue:{0} {1}".format_with(Environment.NewLine, ex.Message)); } }
public void noop(ChocolateyConfiguration configuration) { var templateLocation = _fileSystem.combine_paths(configuration.OutputDirectory ?? _fileSystem.get_current_directory(), configuration.NewCommand.Name); this.Log().Info(() => "Would have generated a new package specification at {0}".format_with(templateLocation)); }
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.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.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 packageCacheLocation = _fileSystem.combine_paths(_fileSystem.get_full_path(config.CacheLocation), pkgInfo.Package.Id, pkgInfo.Package.Version.to_string()); 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 install(ChocolateyConfiguration configuration, PackageResult packageResult) { _fileSystem.create_directory_if_not_exists(ApplicationParameters.ShimsLocation); if (packageResult.InstallLocation.is_equal_to(ApplicationParameters.InstallLocation) || packageResult.InstallLocation.is_equal_to(ApplicationParameters.PackagesLocation)) { var logMessage = "Install location is not specific enough, cannot run shimgen:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, packageResult.InstallLocation); packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); this.Log().Error(logMessage.escape_curly_braces()); return; } //gather all .exes in the folder var exeFiles = _fileSystem.get_files(packageResult.InstallLocation, pattern: "*.exe", option: SearchOption.AllDirectories); foreach (string file in exeFiles.or_empty_list_if_null()) { if (_fileSystem.file_exists(file + ".ignore")) { continue; } bool isGui = _fileSystem.file_exists(file + ".gui"); //todo: v2 be able to determine gui automatically var args = ExternalCommandArgsBuilder.build_arguments(configuration, _shimGenArguments); var shimLocation = _fileSystem.combine_paths(ApplicationParameters.ShimsLocation, _fileSystem.get_file_name(file)); var argsForPackage = args.Replace(PATH_TOKEN, file.Replace(ApplicationParameters.InstallLocation, "..\\")).Replace(OUTPUT_TOKEN, shimLocation).Replace(ICON_PATH_TOKEN, file); if (isGui) { argsForPackage += " --gui"; } var exitCode = _commandExecutor.execute( _shimGenExePath, argsForPackage, configuration.CommandExecutionTimeoutSeconds, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } this.Log().Debug(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces())); }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } this.Log().Error(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces())); }, updateProcessPath: true ); if (exitCode != 0) { Environment.ExitCode = exitCode; } else { this.Log().Info(() => " ShimGen has successfully created a {0}shim for {1}".format_with(isGui ? "gui " : string.Empty, _fileSystem.get_file_name(file))); this.Log().Debug(() => " Created: {0}{1} Targeting: {2}{1} IsGui:{3}{1}".format_with(shimLocation, Environment.NewLine, file, isGui)); } } }
private string get_helpers_folder() { return(_fileSystem.combine_paths(ApplicationParameters.InstallLocation, "helpers")); }
private static void remove_old_chocolatey_exe(IFileSystem fileSystem) { fileSystem.delete_file(Assembly.GetExecutingAssembly().Location + ".old"); fileSystem.delete_file(fileSystem.combine_paths(AppDomain.CurrentDomain.BaseDirectory, "choco.exe.old")); }
//// http://stackoverflow.com/a/8861895/18475 //// http://stackoverflow.com/a/2864714/18475 //[DllImport("kernel32.dll", SetLastError = true)] //private static extern bool SetDllDirectory(string lpPathName); //public struct DieInternal //{ // [SuppressUnmanagedCodeSecurity] // [DllImport("diedll", CallingConvention = CallingConvention.StdCall, EntryPoint = "_DIE_scanExW@20", SetLastError = true)] // internal static extern int scanExW_0([MarshalAs(UnmanagedType.LPWStr)] string pwszFileName, sbyte[] pszOutBuffer, int nOutBufferSize, uint nFlags, [MarshalAs(UnmanagedType.LPWStr)] string pwszDataBase); //} //public string scan_file(string filePath) //{ // if (Platform.get_platform() != PlatformType.Windows) // { // this.Log().Debug("Unable to detect file types when not on Windows"); // return string.Empty; // } // try // { // var successPath = SetDllDirectory(dieDllLocation); // if (!successPath) // { // "chocolatey".Log().Warn("Error during native SetDllDirectory call - {0}".format_with(Marshal.GetLastWin32Error())); // } // var outputBuffer = new sbyte[1024]; // int outputBufferSize = outputBuffer.Length; // const uint flags = DIE_SINGLELINEOUTPUT; // var success = DieInternal.scanExW_0(filePath, outputBuffer, outputBufferSize, flags, databaseLocation); // if (success != 0) // { // "chocolatey".Log().Warn("Error during native _DIE_scanExW call - {0}".format_with(Marshal.GetLastWin32Error())); // } // byte[] outputBytes = Array.ConvertAll(outputBuffer, (a) => (byte)a); // var output = Encoding.UTF8.GetString(outputBytes).to_string().Trim('\0'); // return output; // } // catch (Exception ex) // { // this.Log().Warn("Unable to detect type for '{0}':{1} {2}".format_with(_fileSystem.get_file_name(filePath), Environment.NewLine, ex.Message)); // return string.Empty; // } //} public string scan_file(string filePath) { if (Platform.get_platform() != PlatformType.Windows) { this.Log().Debug("Unable to detect file types when not on Windows"); return(string.Empty); } // http://stackoverflow.com/q/5503951/18475 // http://stackoverflow.com/a/10852827/18475 // http://scottbilas.com/blog/automatically-choose-32-or-64-bit-mixed-mode-dlls/ //todo: convert this to call the exe assembly instead. The dll is 32bit and won't work with AnyCPU filePath = _fileSystem.get_full_path(filePath); var dieDllLocation = _fileSystem.combine_paths(ApplicationParameters.InstallLocation, "tools", "detector"); var diecPath = _fileSystem.combine_paths(ApplicationParameters.InstallLocation, "tools", "detector", "diec.exe"); var databaseLocation = _fileSystem.get_full_path(_fileSystem.combine_paths(ApplicationParameters.InstallLocation, "tools", "detector", "db")); this.Log().Debug("Attempting to detect type for '{0}' with db '{1}'".format_with(_fileSystem.get_file_name(filePath), databaseLocation)); if (!_fileSystem.directory_exists(diecPath) || !_fileSystem.directory_exists(databaseLocation)) { var dieZipLocation = _fileSystem.combine_paths(ApplicationParameters.InstallLocation, "tools", "detector.zip"); unzip_die_files(dieZipLocation, dieDllLocation); // finish unpacking Thread.Sleep(1000); } if (!_fileSystem.file_exists(filePath)) { this.Log().Warn("File not found at '{0}'. Unable to detect type for inexistent file.".format_with(filePath)); return(string.Empty); } try { //todo: detector databaselocation fails now - it's based on the current directory relative path //C:\\ProgramData\\chocolatey\\tools\\detector\\db var output = string.Empty; // var success = CommandExecutor.execute_static(diecPath, "\"{0}\" -singlelineoutput:yes -showoptions:no -showversion:no -database:\"{1}\"".format_with(filePath, databaseLocation), var success = CommandExecutor.execute_static(diecPath, "\"{0}\"".format_with(filePath), 60, _fileSystem.get_current_directory(), (s, e) => { if (!string.IsNullOrWhiteSpace(e.Data)) { output = e.Data; } }, (s, e) => { if (!string.IsNullOrWhiteSpace(e.Data)) { this.Log().Warn("{0}".format_with(e.Data)); } }, false, false); return(output); } catch (Exception ex) { this.Log().Warn("Unable to detect type for '{0}':{1} {2}".format_with(_fileSystem.get_file_name(filePath), Environment.NewLine, ex.Message)); return(string.Empty); } }
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; } 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 (!_fileSystem.file_exists(_configuration.VboxIdPath)) { return; } var vmId = _fileSystem.read_file(_configuration.VboxIdPath); if (string.IsNullOrWhiteSpace(vmId)) { 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; } var vmId = _fileSystem.read_file(_configuration.VboxIdPath); if (string.IsNullOrWhiteSpace(vmId)) { 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); //} }