/// <summary> /// Clean up after the test. /// </summary> /// <param name="removeFiles">True if the files should also be removed. False to leave them behind for debugging purposes.</param> private void Cleanup(bool removeFiles) { PackageBuilder.CleanupByUninstalling(); MSIExec.UninstallAllInstalledProducts(); BundleBuilder.CleanupByUninstalling(); MsiVerifier.Reset(); this.ResetRegistry(); this.ResetDirectory(); if (removeFiles) { foreach (FileSystemInfo artifact in this.TestArtifacts) { try { if (artifact is DirectoryInfo) { Directory.Delete(artifact.FullName, true); } else { artifact.Delete(); } } catch { } } } }
/// <summary> /// Ensures the packages built previously are uninstalled. /// </summary> protected override void UninstallItem(BuiltItem item) { MSIExec exec = new MSIExec(); exec.ExecutionMode = MSIExec.MSIExecMode.Uninstall; exec.OtherArguments = "IGNOREDEPENDENCIES=ALL"; exec.Product = item.Path; // Generate the log file name. string logFile = String.Format("{0}_{1:yyyyMMddhhmmss}_Cleanup_{2}.log", item.TestName, DateTime.UtcNow, Path.GetFileNameWithoutExtension(item.Path)); exec.LogFile = Path.Combine(Path.GetTempPath(), logFile); exec.Run(false); }
/// <summary> /// Executes MSIExec on a .msi file /// </summary> /// <param name="sourceFile">Path the .msi file to use</param> /// <param name="mode">Mode of execution for MSIExec</param> /// <param name="otherArguments">Other arguments to pass to MSIExec.</param> /// <param name="expectedExitCode">Expected exit code</param> /// <returns>MSIExec exit code</returns> private static MSIExecReturnCode RunMSIExec(string sourceFile, MSIExecMode mode, string[] otherArguments, MSIExecReturnCode expectedExitCode, out string logFile) { MSIExec msiexec = new MSIExec(); msiexec.Product = sourceFile; msiexec.ExecutionMode = mode; msiexec.OtherArguments = null != otherArguments?String.Join(" ", otherArguments) : null; msiexec.ExpectedExitCode = expectedExitCode; Result result = msiexec.Run(); logFile = msiexec.LogFile; return((MSIExecReturnCode)result.ExitCode); }
/// <summary> /// Uninitializes a single test case. /// </summary> public virtual void TestUninitialize(MethodResult result) { this.TestUninitialize(); BundleBuilder.CleanupByUninstalling(); PackageBuilder.CleanupByUninstalling(); MSIExec.UninstallAllInstalledProducts(); MsiVerifier.Reset(); this.ResetRegistry(); this.ResetDirectory(); if (this.cleanArtifacts) { foreach (FileSystemInfo artifact in this.TestArtifacts) { if (artifact.Exists) { try { DirectoryInfo dir = artifact as DirectoryInfo; if (null != dir) { dir.Delete(true); } else { artifact.Delete(); } } catch { Debug.WriteLine(String.Format("Failed to delete '{0}'.", artifact.FullName)); } } } } }
/// <summary> /// Attempt to uninstall all the installed msi's /// </summary> /// <remarks> /// TODO: implement ignore_return_code option /// </remarks> public static void UninstallAllInstalledProducts() { foreach (string sourceFile in MSIExec.InstalledMSI) { // This is a best effort attempt to clean up the machine after a test run. // The loop will attempt to uninstall all the msi files registered to be installed. try { string logFile = string.Empty; MSIExecReturnCode exitCode = MSIExec.RunMSIExec(sourceFile, MSIExecMode.Uninstall, null, MSIExecReturnCode.SUCCESS, out logFile); if (MSIExecReturnCode.SUCCESS != exitCode) { Console.WriteLine(string.Format("Failed to uninstall msi '{0}'. Exit code: '{1}'", sourceFile, exitCode.ToString())); } } catch (Exception ex) { Console.WriteLine(string.Format("Failed to uninstall msi '{0}'. Exception raised: '{1}'", sourceFile, ex.Message)); } } MSIExec.InstalledMSI.Clear(); }
/// <summary> /// Executes MSIExec on a .msi file /// </summary> /// <param name="sourceFile">Path the .msi file to use</param> /// <param name="mode">Mode of execution for MSIExec</param> /// <param name="otherArguments">Other arguments to pass to MSIExec.</param> /// <param name="expectedExitCode">Expected exit code</param> /// <returns>MSIExec exit code</returns> private static MSIExecReturnCode RunMSIExec(string sourceFile, MSIExecMode mode, string[] otherArguments, MSIExecReturnCode expectedExitCode, out string logFile) { MSIExec msiexec = new MSIExec(); msiexec.Product = sourceFile; msiexec.ExecutionMode = mode; msiexec.OtherArguments = null != otherArguments ? String.Join(" ", otherArguments) : null; msiexec.ExpectedExitCode = expectedExitCode; Result result = msiexec.Run(); logFile = msiexec.LogFile; return (MSIExecReturnCode)result.ExitCode; }
/// <summary> /// Uninstalls the product and passes zero or more property settings. /// </summary> /// <param name="path">The path to the MSI to install.</param> /// <param name="expectedExitCode">The expected exit code.</param> /// <param name="properties">Zero or more properties to pass to the install.</param> /// <returns>The path to the log file.</returns> private string UninstallProductWithProperties(string path, MSIExec.MSIExecReturnCode expectedExitCode, params string[] properties) { return RunMSIWithProperties(path, expectedExitCode, MSIExec.MSIExecMode.Uninstall, properties); }
/// <summary> /// Runs msiexec on the given <paramref name="path"/> with zero or more property settings. /// </summary> /// <param name="path">The path to the MSI to run.</param> /// <param name="expectedExitCode">The expected exit code.</param> /// <param name="mode">The installation mode for the MSI.</param> /// <param name="properties">Zero or more properties to pass to the install.</param> /// <returns>The path to the log file.</returns> private string RunMSIWithProperties(string path, MSIExec.MSIExecReturnCode expectedExitCode, MSIExec.MSIExecMode mode, params string[] properties) { MSIExec exec = new MSIExec(); exec.ExecutionMode = mode; exec.ExpectedExitCode = expectedExitCode; exec.OtherArguments = null != properties ? String.Join(" ", properties) : null; exec.Product = path; // Get the name of the calling method. StackTrace stack = new StackTrace(); string caller = stack.GetFrame(2).GetMethod().Name; // Generate the log file name. string logFile = String.Format("{0}_{1:yyyyMMddhhmmss}_{3}_{2}.log", caller, DateTime.UtcNow, Path.GetFileNameWithoutExtension(path), mode); exec.LogFile = Path.Combine(Path.GetTempPath(), logFile); exec.Run(); return exec.LogFile; }
/// <summary> /// Executes the bundle with optional arguments. /// </summary> /// <param name="expectedExitCode">Expected exit code.</param> /// <param name="mode">Install mode.</param> /// <param name="arguments">Optional arguments to pass to the tool.</param> /// <returns>Path to the generated log file.</returns> private string RunBundleWithArguments(int expectedExitCode, MSIExec.MSIExecMode mode, params string[] arguments) { TestTool bundle = new TestTool(this.Bundle, null); StringBuilder sb = new StringBuilder(); // Be sure to run silent. sb.Append(" -quiet"); // Generate the log file name. string logFile = Path.Combine(Path.GetTempPath(), String.Format("{0}_{1:yyyyMMddhhmmss}_{3}_{2}.log", this.TestName, DateTime.UtcNow, Path.GetFileNameWithoutExtension(this.Bundle), mode)); sb.AppendFormat(" -log \"{0}\"", logFile); // Set operation. switch (mode) { case MSIExec.MSIExecMode.Modify: sb.Append(" -modify"); break; case MSIExec.MSIExecMode.Repair: sb.Append(" -repair"); break; case MSIExec.MSIExecMode.Uninstall: sb.Append(" -uninstall"); break; } // Add additional arguments. if (null != arguments) { sb.Append(" "); sb.Append(String.Join(" ", arguments)); } // Set the arguments. bundle.Arguments = sb.ToString(); // Run the tool and assert the expected code. bundle.ExpectedExitCode = expectedExitCode; bundle.Run(); // Return the log file name. return logFile; }