/// <summary> /// Main running method for the application. /// </summary> /// <param name="args">Commandline arguments to the application.</param> /// <returns>Returns the application error code.</returns> private int Run(string[] args) { WixToolset.Binder binder = null; Differ differ = null; Unbinder unbinder = null; TempFileCollection tempFileCollection = null; try { // parse the command line this.ParseCommandLine(args); // validate the inputs if (this.xmlInputs && this.adminImage) { this.messageHandler.Display(this, WixErrors.IllegalCommandlineArgumentCombination("a", "xi")); this.showHelp = true; } string[] allValidExtensions = new string[] { wixMstExtension, wixOutExtension, wixPdbExtension, msiExtension }; string[] expectedSingleInputExtensions = new string[] { wixMstExtension, wixOutExtension }; string[] expectedDoubleInputXmlExtensions = new string[] { wixOutExtension, wixPdbExtension }; string[] expectedDoubleInputMsiExtensions = new string[] { msiExtension }; // Validate that all inputs have the correct extension and we dont have too many inputs. if (1 == this.inputFiles.Count) { string inputFile = this.inputFiles[0]; bool hasValidExtension = false; foreach (string extension in expectedSingleInputExtensions) { if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase)) { hasValidExtension = true; break; } } if (!hasValidExtension) { bool missingInput = false; // Check if its using an extension that could be valid in other scenarios. foreach (string validExtension in allValidExtensions) { if (String.Equals(Path.GetExtension(inputFile), validExtension, StringComparison.OrdinalIgnoreCase)) { this.messageHandler.Display(this, WixErrors.WrongFileExtensionForNumberOfInputs(Path.GetExtension(inputFile), inputFile)); missingInput = true; break; } } if (!missingInput) { this.messageHandler.Display(this, WixErrors.UnexpectedFileExtension(inputFile, String.Join(", ", expectedSingleInputExtensions))); } } } else if (2 == this.inputFiles.Count) { foreach (string inputFile in inputFiles) { bool hasValidExtension = false; string[] expectedExtensions = allValidExtensions; if (this.xmlInputs) { foreach (string extension in expectedDoubleInputXmlExtensions) { if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase)) { hasValidExtension = true; expectedExtensions = expectedDoubleInputXmlExtensions; break; } } } else { foreach (string extension in expectedDoubleInputMsiExtensions) { if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase)) { hasValidExtension = true; expectedExtensions = expectedDoubleInputMsiExtensions; break; } } } if (!hasValidExtension) { this.messageHandler.Display(this, WixErrors.UnexpectedFileExtension(inputFile, String.Join(", ", expectedExtensions))); } } } else { this.showHelp = true; } // exit if there was an error parsing the command line or with a file extension (otherwise the logo appears after error messages) if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } if (null == this.outputFile) { this.showHelp = true; } if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { Console.WriteLine(TorchStrings.HelpMessage); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } foreach (string parameter in this.invalidArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } this.invalidArgs = null; binder = new WixToolset.Binder(); differ = new Differ(); unbinder = new Unbinder(); // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); unbinder.AddExtension(wixExtension); binder.AddExtension(wixExtension); differ.AddExtension(wixExtension); } binder.Message += new MessageEventHandler(this.messageHandler.Display); differ.Message += new MessageEventHandler(this.messageHandler.Display); unbinder.Message += new MessageEventHandler(this.messageHandler.Display); binder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); unbinder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); tempFileCollection = new TempFileCollection(Environment.GetEnvironmentVariable("WIX_TEMP")); binder.WixVariableResolver = new WixVariableResolver(); differ.PreserveUnchangedRows = this.preserveUnchangedRows; differ.ShowPedanticMessages = this.showPedanticMessages; unbinder.SuppressExtractCabinets = true; unbinder.IsAdminImage = this.adminImage; if (null == this.exportBasePath) { this.exportBasePath = tempFileCollection.BasePath; } // load and process the inputs Output transform; if (1 == this.inputFiles.Count) { transform = Output.Load(this.inputFiles[0], false, false); if (OutputType.Transform != transform.Type) { this.messageHandler.Display(this, WixErrors.InvalidWixTransform(this.inputFiles[0])); return(this.messageHandler.LastErrorNumber); } } else // 2 inputs { Output targetOutput; Output updatedOutput; if (this.xmlInputs) { // load the target database if (String.Equals(Path.GetExtension(inputFiles[0]), wixPdbExtension, StringComparison.OrdinalIgnoreCase)) { Pdb targetPdb = Pdb.Load(this.inputFiles[0], false, false); targetOutput = targetPdb.Output; } else { targetOutput = Output.Load(this.inputFiles[0], false, false); } // load the updated database if (String.Equals(Path.GetExtension(inputFiles[1]), wixPdbExtension, StringComparison.OrdinalIgnoreCase)) { Pdb updatedPdb = Pdb.Load(this.inputFiles[1], false, false); updatedOutput = updatedPdb.Output; } else { updatedOutput = Output.Load(this.inputFiles[1], false, false); } this.xmlOutput = true; } else { // load the target database targetOutput = unbinder.Unbind(this.inputFiles[0], OutputType.Product, Path.Combine(this.exportBasePath, "targetBinaries")); // load the updated database updatedOutput = unbinder.Unbind(this.inputFiles[1], OutputType.Product, Path.Combine(this.exportBasePath, "updatedBinaries")); } // diff the target and updated databases transform = differ.Diff(targetOutput, updatedOutput, this.validationFlags); if (null == transform.Tables || 0 >= transform.Tables.Count) { throw new WixException(WixErrors.NoDifferencesInTransform(transform.SourceLineNumbers)); } } // output the transform if (null != transform) { // If either the user selected xml output or gave xml input, save as xml output. // With xml inputs, many funtions of the binder have not been performed on the inputs (ie. file sequencing). This results in bad IDT files which cannot be put in a transform. if (this.xmlOutput) { transform.Save(this.outputFile, null, null, tempFileCollection.BasePath); } else { binder.Bind(transform, this.outputFile); } } } catch (WixException we) { if (we is WixInvalidIdtException) { // make sure the IDT files stay around this.tidy = false; } this.messageHandler.Display(this, we.Error); } catch (Exception e) { // make sure the files stay around for debugging this.tidy = false; this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } finally { if (null != binder) { if (this.tidy) { if (!binder.DeleteTempFiles()) { Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, binder.TempFilesLocation); } } else { Console.WriteLine(TorchStrings.INF_BinderTempDirLocatedAt, binder.TempFilesLocation); } } if (null != unbinder) { if (this.tidy) { if (!unbinder.DeleteTempFiles()) { Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, binder.TempFilesLocation); } } else { Console.WriteLine(TorchStrings.INF_UnbinderTempDirLocatedAt, binder.TempFilesLocation); } } if (null != tempFileCollection) { if (this.tidy) { try { Directory.Delete(tempFileCollection.BasePath, true); } catch (DirectoryNotFoundException) { // if the path doesn't exist, then there is nothing for us to worry about } catch { Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, tempFileCollection.BasePath); } } else { Console.WriteLine(TorchStrings.INF_TorchTempDirLocatedAt, tempFileCollection.BasePath); } } } return(this.messageHandler.LastErrorNumber); }
/// <summary> /// Main running method for the application. /// </summary> /// <param name="args">Commandline arguments to the application.</param> /// <returns>Returns the application error code.</returns> private int Run(string[] args) { try { // parse the command line this.ParseCommandLine(args); // exit if there was an error parsing the command line (otherwise the logo appears after error messages) if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } if (null == this.inputFile || null == this.outputFile) { this.showHelp = true; } if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { Console.WriteLine(PyroStrings.HelpMessage); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } // Load in transforms ArrayList transforms = new ArrayList(); foreach (string inputTransform in inputTransformsOrdered) { PatchTransform patchTransform = new PatchTransform(inputTransform, inputTransforms[inputTransform]); patchTransform.Message += new MessageEventHandler(this.messageHandler.Display); transforms.Add(patchTransform); } // Create and configure the patch Patch patch = new Patch(); patch.Message += new MessageEventHandler(this.messageHandler.Display); // Create and configure the binder binder = new WixToolset.Binder(); binder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); binder.WixVariableResolver = this.wixVariableResolver; binder.Message += new MessageEventHandler(this.messageHandler.Display); binder.SuppressAssemblies = this.suppressAssemblies; binder.SuppressFileHashAndInfo = this.suppressFileHashAndInfo; binder.SetMsiAssemblyNameFileVersion = this.setAssemblyFileVersions; // have the binder parse the command line arguments light did not recognize string[] unparsedArgsArray = new string[this.unparsedArgs.Count]; this.unparsedArgs.CopyTo(unparsedArgsArray, 0); StringCollection remainingArgs = this.binder.ParseCommandLine(unparsedArgsArray, this.messageHandler); // Load the extensions bool binderFileManagerLoaded = false; foreach (String extension in this.extensions) { WixExtension wixExtension = WixExtension.Load(extension); binder.AddExtension(wixExtension); patch.AddExtension(wixExtension); if (0 < remainingArgs.Count) { remainingArgs = wixExtension.ParseCommandLine(remainingArgs, this.messageHandler); } if (null != wixExtension.BinderFileManager) { if (binderFileManagerLoaded) { throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, PyroStrings.EXP_CannotLoadBinderFileManager, wixExtension.BinderFileManager.GetType().ToString(), binder.FileManager.ToString()), "ext"); } binder.FileManager = wixExtension.BinderFileManager; binderFileManagerLoaded = true; } } foreach (string parameter in remainingArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } // since the binder is now ready, let's plug dynamic bindpath into file manager this.PrepareDataForFileManager(); // Load the patch patch.Load(this.inputFile); // Copy transforms into output if (0 < transforms.Count) { patch.AttachTransforms(transforms); } if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } if (null == this.pdbFile && null != this.outputFile) { this.pdbFile = Path.ChangeExtension(this.outputFile, ".wixpdb"); } binder.PdbFile = suppressWixPdb ? null : this.pdbFile; if (this.suppressFiles) { binder.SuppressAssemblies = true; binder.SuppressFileHashAndInfo = true; } if (null != this.cabCachePath || this.reuseCabinets) { // ensure the cabinet cache path exists if we are going to use it if (null != this.cabCachePath && !Directory.Exists(this.cabCachePath)) { Directory.CreateDirectory(this.cabCachePath); } } binder.FileManager.ReuseCabinets = this.reuseCabinets; binder.FileManager.CabCachePath = this.cabCachePath; binder.FileManager.Output = patch.PatchOutput; binder.FileManager.DeltaBinaryPatch = this.delta; // Bind the patch to an msp. binder.Bind(patch.PatchOutput, this.outputFile); } catch (WixException we) { this.OnMessage(we.Error); } catch (Exception e) { this.OnMessage(WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } finally { if (null != binder) { if (this.tidy) { if (!binder.DeleteTempFiles()) { Console.WriteLine(PyroStrings.WAR_FailedToDeleteTempDir, binder.TempFilesLocation); } } else { Console.WriteLine(PyroStrings.INF_TempDirLocatedAt, binder.TempFilesLocation); } } } return(this.messageHandler.LastErrorNumber); }