/// <summary> /// Load sections from the input files. /// </summary> /// <returns>Returns a section collection.</returns> private Dictionary <Section, string> LoadFragments() { // we need a Linker and the extensions for their table definitions Linker linker = new Linker(); linker.Message += new MessageEventHandler(this.Message); if (null != this.extensionList) { foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); linker.AddExtension(wixExtension); } } // load each intermediate and library file and get their sections Dictionary <Section, string> sectionFiles = new Dictionary <Section, string>(); if (null != this.inputFiles) { foreach (string inputFile in this.inputFiles) { string inputFileFullPath = Path.GetFullPath(inputFile); if (File.Exists(inputFileFullPath)) { // try loading as an object file try { Intermediate intermediate = Intermediate.Load(inputFileFullPath, linker.TableDefinitions, false, false); Generator.LoadSections(inputFile, sectionFiles, intermediate.Sections); continue; // next file } catch (WixNotIntermediateException) { // try another format } // try loading as a library file try { Library library = Library.Load(inputFileFullPath, linker.TableDefinitions, false, false); Generator.LoadSections(inputFile, sectionFiles, library.Sections); continue; // next file } catch (WixNotLibraryException) { this.OnMessage(LuxBuildErrors.CouldntLoadInput(inputFile)); } } } } return(sectionFiles); }
public override Library GetLibrary( TableDefinitionCollection tableDefinitions) { if (this.library == null) { this.library = WixExtension.LoadLibraryHelper( Assembly.GetExecutingAssembly(), "WixGAExtension.GALibrary.wixlib", tableDefinitions); } return(this.library); }
/// <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) { Microsoft.Tools.WindowsInstallerXml.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 Microsoft.Tools.WindowsInstallerXml.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 (!this.fipsCompliant) { try { System.Security.Cryptography.MD5.Create(); } catch (TargetInvocationException) { this.messageHandler.Display(this, WixErrors.UseFipsArgument()); return(this.messageHandler.LastErrorNumber); } } if (0 == this.sourceFiles.Count) { this.showHelp = true; } else if (1 < this.sourceFiles.Count && null != this.outputFile) { throw new ArgumentException(CandleStrings.CannotSpecifyMoreThanOneSourceFileForSingleTargetFile, "-out"); } if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { Console.WriteLine(CandleStrings.HelpMessage); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } foreach (string parameter in this.invalidArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } this.invalidArgs = null; // create the preprocessor and compiler Preprocessor preprocessor = new Preprocessor(); preprocessor.Message += new MessageEventHandler(this.messageHandler.Display); for (int i = 0; i < this.includeSearchPaths.Count; ++i) { preprocessor.IncludeSearchPaths.Add(this.includeSearchPaths[i]); } preprocessor.CurrentPlatform = this.platform; Compiler compiler = new Compiler(); compiler.Message += new MessageEventHandler(this.messageHandler.Display); compiler.SuppressFilesVitalByDefault = this.suppressFilesVitalByDefault; compiler.ShowPedanticMessages = this.showPedanticMessages; compiler.SuppressValidate = this.suppressSchema; compiler.CurrentPlatform = this.platform; compiler.FipsCompliant = this.fipsCompliant; // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); preprocessor.AddExtension(wixExtension); compiler.AddExtension(wixExtension); } // preprocess then compile each source file Dictionary <string, List <string> > sourcesForOutput = new Dictionary <string, List <string> >(StringComparer.OrdinalIgnoreCase); foreach (string sourceFileOrig in this.sourceFiles) { string sourceFile = sourceFileOrig; string targetFile = null; if (this.allowPerSourceOutputSpecification) { string[] parts = sourceFileOrig.Split(Candle.sourceOutputSeparator, 2); if (2 == parts.Length) { sourceFile = parts[0]; targetFile = parts[1]; } } string sourceFilePath = Path.GetFullPath(sourceFile); string sourceFileName = Path.GetFileName(sourceFile); if (null == targetFile) { if (null != this.outputFile) { targetFile = this.outputFile; } else if (null != this.outputDirectory) { targetFile = Path.Combine(this.outputDirectory, Path.ChangeExtension(sourceFileName, ".wixobj")); } else { targetFile = Path.ChangeExtension(sourceFileName, ".wixobj"); } } else if (!Path.IsPathRooted(targetFile) && null != this.outputDirectory) { targetFile = Path.Combine(this.outputDirectory, targetFile); } // print friendly message saying what file is being compiled Console.WriteLine(sourceFileName); // preprocess the source XmlDocument sourceDocument; try { if (this.preprocessToStdout) { preprocessor.PreprocessOut = Console.Out; } else if (null != this.preprocessFile) { preprocessor.PreprocessOut = new StreamWriter(this.preprocessFile); } sourceDocument = preprocessor.Process(sourceFilePath, this.parameters); } finally { if (null != preprocessor.PreprocessOut && Console.Out != preprocessor.PreprocessOut) { preprocessor.PreprocessOut.Close(); } } // if we're not actually going to compile anything, move on to the next file if (null == sourceDocument || this.preprocessToStdout || null != this.preprocessFile) { continue; } // and now we do what we came here to do... Intermediate intermediate = compiler.Compile(sourceDocument); // save the intermediate to disk if no errors were found for this source file if (null != intermediate) { intermediate.Save(targetFile); } // Track which source files result in a given output file, to ensure we aren't // overwriting the output. List <string> sources = null; string targetPath = Path.GetFullPath(targetFile); if (!sourcesForOutput.TryGetValue(targetPath, out sources)) { sources = new List <string>(); sourcesForOutput.Add(targetPath, sources); } sources.Add(sourceFile); } // Show an error for every output file that had more than 1 source file. foreach (KeyValuePair <string, List <string> > outputSources in sourcesForOutput) { if (1 < outputSources.Value.Count) { string sourceFiles = CompilerCore.CreateValueList(ValueListKind.None, outputSources.Value); this.messageHandler.Display(this, WixErrors.DuplicateSourcesForOutput(sourceFiles, outputSources.Key)); } } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } 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) { Linker linker = null; Localizer localizer = null; SectionCollection sections = new SectionCollection(); ArrayList transforms = new ArrayList(); try { // parse the command line this.ParseCommandLine(args); // load any extensions List <WixExtension> loadedExtensionList = new List <WixExtension>(); foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); loadedExtensionList.Add(wixExtension); // If the extension provides a binder, use that now if it // matches the class from the command line. if (null != wixExtension.CustomBinder && null != this.binderClass && wixExtension.CustomBinder.GetType().Name.Equals(this.binderClass, StringComparison.Ordinal)) { this.binder = wixExtension.CustomBinder; } } // If a binder was specified, but not found then show an error. if (!String.IsNullOrEmpty(this.binderClass) && null == this.binder) { throw new WixException(WixErrors.SpecifiedBinderNotFound(this.binderClass)); } // create the linker, binder, and validator linker = new Linker(); if (null == this.binder) { this.binder = new Microsoft.Tools.WindowsInstallerXml.Binder(); } // 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); // Loop through the extensions to give them a shot at processing the remaining command-line args. foreach (WixExtension wixExtension in loadedExtensionList) { if (0 == remainingArgs.Count) { break; } remainingArgs = wixExtension.ParseCommandLine(remainingArgs, this.messageHandler); } this.ParseCommandLinePassTwo(remainingArgs); // 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); } foreach (string parameter in this.invalidArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } this.invalidArgs = null; // 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 (0 == this.inputFiles.Count) { this.showHelp = true; } else if (null == this.outputFile) { if (1 < this.inputFiles.Count) { throw new WixException(WixErrors.MustSpecifyOutputWithMoreThanOneInput()); } this.outputFile = Path.ChangeExtension(Path.GetFileName(this.inputFiles[0]), ".wix"); // we'll let the linker change the extension later } this.binder.OutputFile = this.outputFile; this.binder.PostParseCommandLine(); if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { this.PrintHelp(); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } linker.AllowIdenticalRows = this.allowIdenticalRows; linker.AllowUnresolvedReferences = this.allowUnresolvedReferences; linker.Cultures = this.cultures; linker.UnreferencedSymbolsFile = this.unreferencedSymbolsFile; linker.ShowPedanticMessages = this.showPedanticMessages; linker.DropUnrealTables = this.dropUnrealTables; linker.SuppressLocalization = this.suppressLocalization; linker.SuppressMsiAssemblyTable = this.suppressMsiAssemblyTable; linker.WixVariableResolver = this.wixVariableResolver; // set the sequence suppression options linker.SuppressAdminSequence = this.suppressAdminSequence; linker.SuppressAdvertiseSequence = this.suppressAdvertiseSequence; linker.SuppressUISequence = this.suppressUISequence; linker.SectionIdOnRows = this.sectionIdOnRows; this.binder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); this.binder.WixVariableResolver = this.wixVariableResolver; if (null != this.bindPaths) { foreach (string bindPath in this.bindPaths) { if (-1 == bindPath.IndexOf('=')) { this.sourcePaths.Add(bindPath); } } } // instantiate the localizer and load any localization files if (!this.suppressLocalization || 0 < this.localizationFiles.Count || null != this.cultures || !this.outputXml) { List <Localization> localizations = new List <Localization>(); localizer = new Localizer(); localizer.Message += new MessageEventHandler(this.messageHandler.Display); // load each localization file foreach (string localizationFile in this.localizationFiles) { Localization localization = Localization.Load(localizationFile, linker.TableDefinitions, this.suppressSchema); localizations.Add(localization); } if (null != this.cultures) { // add localizations in order specified in cultures foreach (string culture in this.cultures) { foreach (Localization localization in localizations) { if (culture.Equals(localization.Culture, StringComparison.OrdinalIgnoreCase)) { localizer.AddLocalization(localization); } } } } else { bool neutralFound = false; foreach (Localization localization in localizations) { if (0 == localization.Culture.Length) { // if a neutral wxl was provided use it localizer.AddLocalization(localization); neutralFound = true; } } if (!neutralFound) { // cultures wasn't specified and no neutral wxl are available, include all of the files foreach (Localization localization in localizations) { localizer.AddLocalization(localization); } } } // immediately stop processing if any errors were found if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } // tell all of the objects about the localizer linker.Localizer = localizer; this.binder.Localizer = localizer; this.wixVariableResolver.Localizer = localizer; } // process loaded extensions foreach (WixExtension wixExtension in loadedExtensionList) { linker.AddExtension(wixExtension); this.binder.AddExtension(wixExtension); // load the extension's localizations Library library = wixExtension.GetLibrary(linker.TableDefinitions); if (null != library) { // load the extension's default culture if it provides one and we don't specify any cultures string[] extensionCultures = this.cultures; if (null == extensionCultures && null != wixExtension.DefaultCulture) { extensionCultures = new string[] { wixExtension.DefaultCulture }; } library.GetLocalizations(extensionCultures, localizer); } } this.binder.ProcessExtensions(loadedExtensionList.ToArray()); // set the message handlers linker.Message += new MessageEventHandler(this.messageHandler.Display); this.binder.AddMessageEventHandler(new MessageEventHandler(this.messageHandler.Display)); Output output = null; // loop through all the believed object files foreach (string inputFile in this.inputFiles) { string dirName = Path.GetDirectoryName(inputFile); string inputFileFullPath = Path.GetFullPath(inputFile); if (!this.sourcePaths.Contains(dirName)) { this.sourcePaths.Add(dirName); } // try loading as an object file try { Intermediate intermediate = Intermediate.Load(inputFileFullPath, linker.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); sections.AddRange(intermediate.Sections); continue; // next file } catch (WixNotIntermediateException) { // try another format } // try loading as a library file try { Library library = Library.Load(inputFileFullPath, linker.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); library.GetLocalizations(this.cultures, localizer); sections.AddRange(library.Sections); continue; // next file } catch (WixNotLibraryException) { // try another format } // try loading as an output file output = Output.Load(inputFileFullPath, this.suppressVersionCheck, this.suppressSchema); } // immediately stop processing if any errors were found if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } // set the binder file manager information foreach (string bindPath in this.bindPaths) { //Checking as IndexOf will return 0 if the string value is String.Empty. if (String.IsNullOrEmpty(bindPath)) { continue; } if (-1 == bindPath.IndexOf('=')) { this.binder.FileManager.BindPaths.Add(bindPath); } else { string[] namedPair = bindPath.Split('='); //It is ok to have duplicate key. this.binder.FileManager.NamedBindPaths.Add(namedPair[0], namedPair[1]); } } foreach (string sourcePath in this.sourcePaths) { this.binder.FileManager.SourcePaths.Add(sourcePath); } // and now for the fun part if (null == output) { OutputType expectedOutputType = OutputType.Unknown; if (this.outputFile != null) { expectedOutputType = Output.GetOutputType(Path.GetExtension(this.outputFile)); } output = linker.Link(sections, transforms, expectedOutputType); // if an error occurred during linking, stop processing if (null == output) { return(this.messageHandler.LastErrorNumber); } } else if (0 != sections.Count) { throw new InvalidOperationException(LightStrings.EXP_CannotLinkObjFilesWithOutpuFile); } // Now that the output object is either linked or loaded, tell the binder file manager about it. this.binder.FileManager.Output = output; // only output the xml if its a patch build or user specfied to only output wixout if (this.outputXml || OutputType.Patch == output.Type) { string outputExtension = Path.GetExtension(this.outputFile); if (null == outputExtension || 0 == outputExtension.Length || ".wix" == outputExtension) { if (OutputType.Patch == output.Type) { this.outputFile = Path.ChangeExtension(this.outputFile, ".wixmsp"); } else { this.outputFile = Path.ChangeExtension(this.outputFile, ".wixout"); } } output.Save(this.outputFile, (this.bindFiles ? this.binder.FileManager : null), this.wixVariableResolver, this.binder.TempFilesLocation); } else // finish creating the MSI/MSM { string outputExtension = Path.GetExtension(this.outputFile); if (null == outputExtension || 0 == outputExtension.Length || ".wix" == outputExtension) { outputExtension = Output.GetExtension(output.Type); this.outputFile = Path.ChangeExtension(this.outputFile, outputExtension); } this.binder.Bind(output, 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) { this.binder.Cleanup(this.tidy); } } 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 { Librarian librarian = null; SectionCollection sections = new SectionCollection(); // 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 (0 == this.inputFiles.Count) { this.showHelp = true; } else if (null == this.outputFile) { if (1 < this.inputFiles.Count) { throw new ArgumentException("must specify output file when using more than one input file", "-out"); } // we'll let the linker change the extension later this.outputFile = Path.ChangeExtension(this.inputFiles[0], ".wix"); } if (this.showLogo) { Assembly litAssembly = Assembly.GetExecutingAssembly(); Console.WriteLine("Microsoft (R) Windows Installer Xml Library Tool version {0}", litAssembly.GetName().Version.ToString()); Console.WriteLine("Copyright (C) Microsoft Corporation 2003. All rights reserved."); Console.WriteLine(); } if (this.showHelp) { Console.WriteLine(" usage: lit.exe [-?] [-nologo] [-out libraryFile] objectFile [objectFile ...]"); Console.WriteLine(); Console.WriteLine(" -nologo skip printing lit logo information"); Console.WriteLine(" -out specify output file (default: write to current directory)"); Console.WriteLine(); Console.WriteLine(" -b base path to locate all files (default: current directory)"); Console.WriteLine(" -bf bind files into the library file"); Console.WriteLine(" -ext extension assembly or \"class, assembly\""); Console.WriteLine(" -loc <loc.wxl> bind localization strings from a wxl into the library file"); Console.WriteLine(" -ss suppress schema validation of documents (performance boost)"); Console.WriteLine(" -sv suppress intermediate file version mismatch checking"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -v verbose output"); Console.WriteLine(" -? this help information"); Console.WriteLine(); Console.WriteLine("Common extensions:"); Console.WriteLine(" .wxs - Windows installer Xml Source file"); Console.WriteLine(" .wxi - Windows installer Xml Include file"); Console.WriteLine(" .wixobj - Windows installer Xml Object file (in XML format)"); Console.WriteLine(" .wixlib - Windows installer Xml Library file (in XML format)"); Console.WriteLine(" .wixout - Windows installer Xml Output file (in XML format)"); Console.WriteLine(); Console.WriteLine(" .msm - Windows installer Merge Module"); Console.WriteLine(" .msi - Windows installer Product Database"); Console.WriteLine(" .msp - Windows installer Patch"); Console.WriteLine(" .mst - Windows installer Transform"); Console.WriteLine(" .pcp - Windows installer Patch Creation Package"); Console.WriteLine(); Console.WriteLine("For more information see: http://wix.sourceforge.net"); return(this.messageHandler.LastErrorNumber); } // create the librarian librarian = new Librarian(); librarian.Message += new MessageEventHandler(this.messageHandler.Display); if (null != this.basePaths) { foreach (string basePath in this.basePaths) { this.sourcePaths.Add(basePath); } } // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); librarian.AddExtension(wixExtension); // load the binder extension regardless of whether it will be used in case there is a collision if (null != wixExtension.BinderExtension) { if (null != this.binderExtension) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "cannot load binder extension: {0}. lit can only load one binder extension and has already loaded binder extension: {1}.", wixExtension.BinderExtension.GetType().ToString(), this.binderExtension.GetType().ToString()), "ext"); } this.binderExtension = wixExtension.BinderExtension; } } // add the sections to the librarian foreach (string inputFile in this.inputFiles) { string inputFileFullPath = Path.GetFullPath(inputFile); string dirName = Path.GetDirectoryName(inputFileFullPath); if (!this.sourcePaths.Contains(dirName)) { this.sourcePaths.Add(dirName); } // try loading as an object file try { Intermediate intermediate = Intermediate.Load(inputFileFullPath, librarian.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); sections.AddRange(intermediate.Sections); continue; // next file } catch (WixNotIntermediateException) { // try another format } // try loading as a library file Library loadedLibrary = Library.Load(inputFileFullPath, librarian.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); sections.AddRange(loadedLibrary.Sections); } // and now for the fun part Library library = librarian.Combine(sections); // save the library output if an error did not occur if (null != library) { if (this.bindFiles) { // if the binder extension has not been loaded yet use the built-in binder extension if (null == this.binderExtension) { this.binderExtension = new BinderExtension(); } // set the binder extension information foreach (string basePath in this.basePaths) { this.binderExtension.BasePaths.Add(basePath); } foreach (string sourcePath in this.sourcePaths) { this.binderExtension.SourcePaths.Add(sourcePath); } } else { this.binderExtension = null; } foreach (string localizationFile in this.localizationFiles) { Localization localization = Localization.Load(localizationFile, librarian.TableDefinitions, this.suppressSchema); library.AddLocalization(localization); } WixVariableResolver wixVariableResolver = new WixVariableResolver(); wixVariableResolver.Message += new MessageEventHandler(this.messageHandler.Display); library.Save(this.outputFile, this.binderExtension, wixVariableResolver); } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } 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 { Librarian librarian = null; SectionCollection sections = new SectionCollection(); // parse the command line this.ParseCommandLine(args); // load any extensions List <WixExtension> loadedExtensionList = new List <WixExtension>(); foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); loadedExtensionList.Add(wixExtension); // Have the binder extension parse the command line arguments lit did not recognized. if (0 < this.unparsedArgs.Count) { this.unparsedArgs = wixExtension.ParseCommandLine(this.unparsedArgs, this.messageHandler); } } this.ParseCommandLinePassTwo(this.unparsedArgs); // 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 (0 == this.inputFiles.Count) { this.showHelp = true; } else if (null == this.outputFile) { if (1 < this.inputFiles.Count) { throw new WixException(WixErrors.MustSpecifyOutputWithMoreThanOneInput()); } this.outputFile = Path.ChangeExtension(Path.GetFileName(this.inputFiles[0]), ".wixlib"); } if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { Console.WriteLine(LitStrings.HelpMessage); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } foreach (string parameter in this.invalidArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } this.invalidArgs = null; // create the librarian librarian = new Librarian(); librarian.Message += new MessageEventHandler(this.messageHandler.Display); librarian.ShowPedanticMessages = this.showPedanticMessages; if (null != this.bindPaths) { foreach (string bindPath in this.bindPaths) { if (-1 == bindPath.IndexOf('=')) { this.sourcePaths.Add(bindPath); } } } foreach (WixExtension wixExtension in loadedExtensionList) { librarian.AddExtension(wixExtension); // load the binder file manager regardless of whether it will be used in case there is a collision if (null != wixExtension.BinderFileManager) { if (null != this.binderFileManager) { throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, LitStrings.EXP_CannotLoadBinderFileManager, wixExtension.BinderFileManager.GetType().ToString(), this.binderFileManager.GetType().ToString()), "ext"); } this.binderFileManager = wixExtension.BinderFileManager; } } // add the sections to the librarian foreach (string inputFile in this.inputFiles) { string inputFileFullPath = Path.GetFullPath(inputFile); string dirName = Path.GetDirectoryName(inputFileFullPath); if (!this.sourcePaths.Contains(dirName)) { this.sourcePaths.Add(dirName); } // try loading as an object file try { Intermediate intermediate = Intermediate.Load(inputFileFullPath, librarian.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); sections.AddRange(intermediate.Sections); continue; // next file } catch (WixNotIntermediateException) { // try another format } // try loading as a library file Library loadedLibrary = Library.Load(inputFileFullPath, librarian.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); sections.AddRange(loadedLibrary.Sections); } // and now for the fun part Library library = librarian.Combine(sections); // save the library output if an error did not occur if (null != library) { if (this.bindFiles) { // if the binder file manager has not been loaded yet use the built-in binder extension if (null == this.binderFileManager) { this.binderFileManager = new BinderFileManager(); } if (null != this.bindPaths) { foreach (string bindPath in this.bindPaths) { if (-1 == bindPath.IndexOf('=')) { this.binderFileManager.BindPaths.Add(bindPath); } else { string[] namedPair = bindPath.Split('='); //It is ok to have duplicate key. this.binderFileManager.NamedBindPaths.Add(namedPair[0], namedPair[1]); } } } foreach (string sourcePath in this.sourcePaths) { this.binderFileManager.SourcePaths.Add(sourcePath); } } else { this.binderFileManager = null; } foreach (string localizationFile in this.localizationFiles) { Localization localization = Localization.Load(localizationFile, librarian.TableDefinitions, this.suppressSchema); library.AddLocalization(localization); } WixVariableResolver wixVariableResolver = new WixVariableResolver(); wixVariableResolver.Message += new MessageEventHandler(this.messageHandler.Display); library.Save(this.outputFile, this.binderFileManager, wixVariableResolver); } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } 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 (0 == this.inputFiles.Count) { this.showHelp = true; } if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { Console.WriteLine(SmokeStrings.HelpMessage); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } foreach (string parameter in this.invalidArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } this.invalidArgs = null; validator.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); // load any extensions bool validatorExtensionLoaded = false; foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); ValidatorExtension validatorExtension = wixExtension.ValidatorExtension; if (null != validatorExtension) { if (validatorExtensionLoaded) { throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, SmokeStrings.EXP_CannotLoadLinkerExtension, validatorExtension.GetType().ToString(), validator.Extension.ToString()), "ext"); } validator.Extension = validatorExtension; validatorExtensionLoaded = true; } } // set the message handlers validator.Extension.Message += new MessageEventHandler(this.messageHandler.Display); // disable ICE33 and ICE66 by default this.suppressICEs.Add("ICE33"); this.suppressICEs.Add("ICE66"); // set the ICEs string[] iceArray = new string[this.ices.Count]; this.ices.CopyTo(iceArray, 0); validator.ICEs = iceArray; // set the suppressed ICEs string[] suppressICEArray = new string[this.suppressICEs.Count]; this.suppressICEs.CopyTo(suppressICEArray, 0); validator.SuppressedICEs = suppressICEArray; // Load the pdb and assign the Output to the validator if (null != pdbPath) { string pdbFullPath = Path.GetFullPath(pdbPath); Pdb pdb = Pdb.Load(pdbFullPath, false, false); this.validator.Output = pdb.Output; } foreach (string inputFile in this.inputFiles) { // set the default cube file Assembly assembly = Assembly.GetExecutingAssembly(); string appDirectory = Path.GetDirectoryName(assembly.Location); if (this.addDefault) { switch (Path.GetExtension(inputFile).ToLower(CultureInfo.InvariantCulture)) { case msm: validator.AddCubeFile(Path.Combine(appDirectory, "mergemod.cub")); break; case msi: validator.AddCubeFile(Path.Combine(appDirectory, "darice.cub")); break; default: throw new WixException(WixErrors.UnexpectedFileExtension(inputFile, ".msi, .msm")); } } // print friendly message saying what file is being validated Console.WriteLine(Path.GetFileName(inputFile)); Stopwatch stopwatch = Stopwatch.StartNew(); try { validator.Validate(Path.GetFullPath(inputFile)); } catch (UnauthorizedAccessException) { this.messageHandler.Display(this, WixErrors.UnauthorizedAccess(Path.GetFullPath(inputFile))); } finally { stopwatch.Stop(); this.messageHandler.Display(this, WixVerboses.ValidatedDatabase(stopwatch.ElapsedMilliseconds)); if (this.tidy) { if (!validator.DeleteTempFiles()) { Console.WriteLine(SmokeStrings.WAR_FailedToDeleteTempDir, validator.TempFilesLocation); } } else { Console.WriteLine(SmokeStrings.INF_TempDirLocatedAt, validator.TempFilesLocation); } } } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } 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) { Decompiler decompiler = null; Mutator mutator = null; Unbinder unbinder = null; 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) { this.showHelp = true; } else if (null == this.outputFile) { if (null == this.outputDirectory) { this.outputFile = Path.ChangeExtension(Path.GetFileName(this.inputFile), ".wxs"); } else { this.outputFile = Path.Combine(this.outputDirectory, Path.ChangeExtension(Path.GetFileName(this.inputFile), ".wxs")); } } if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { Console.WriteLine(DarkStrings.HelpMessage); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } foreach (string parameter in this.invalidArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } this.invalidArgs = null; // create the decompiler and mutator decompiler = new Decompiler(); mutator = new Mutator(); mutator.Core = new HarvesterCore(new MessageEventHandler(this.messageHandler.Display)); unbinder = new Unbinder(); // read the configuration file (dark.exe.config) AppCommon.ReadConfiguration(this.extensionList); // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); decompiler.AddExtension(wixExtension); unbinder.AddExtension(wixExtension); } // set options decompiler.SuppressCustomTables = this.suppressCustomTables; decompiler.SuppressDroppingEmptyTables = this.suppressDroppingEmptyTables; decompiler.SuppressRelativeActionSequencing = this.suppressRelativeActionSequencing; decompiler.SuppressUI = this.suppressUI; decompiler.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); if (!String.IsNullOrEmpty(this.exportBasePath)) { decompiler.ExportFilePath = this.exportBasePath; } unbinder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); decompiler.Message += new MessageEventHandler(this.messageHandler.Display); unbinder.Message += new MessageEventHandler(this.messageHandler.Display); // print friendly message saying what file is being decompiled Console.WriteLine(Path.GetFileName(this.inputFile)); // unbind // TODO: passing a bundle to the decompiler without the /x parameter specified stumbles here // as the exportBasePath will be null. Need a design decision whether to throw an // message below or throw a message here Output output = unbinder.Unbind(this.inputFile, this.outputType, this.exportBasePath); if (null != output) { if (OutputType.Patch == this.outputType || OutputType.Transform == this.outputType || this.outputXml) { output.Save(this.outputFile, null, new WixVariableResolver(), null); } else // decompile { Wix.Wix wix = decompiler.Decompile(output); // output if (null != wix) { XmlTextWriter writer = null; // mutate the Wix document if (!mutator.Mutate(wix)) { return(this.messageHandler.LastErrorNumber); } try { Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(this.outputFile))); writer = new XmlTextWriter(this.outputFile, System.Text.Encoding.UTF8); writer.Indentation = 4; writer.IndentChar = ' '; writer.QuoteChar = '"'; writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); wix.OutputXml(writer); writer.WriteEndDocument(); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.FileWriteError(this.outputFile, e.Message)); return(this.messageHandler.LastErrorNumber); } finally { if (null != writer) { writer.Close(); } } } } } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } finally { if (null != decompiler) { if (this.tidy) { if (!decompiler.DeleteTempFiles()) { Console.WriteLine(DarkStrings.WAR_FailedToDeleteTempDir, decompiler.TempFilesLocation); } } else { Console.WriteLine(DarkStrings.INF_TempDirLocatedAt, decompiler.TempFilesLocation); } } if (null != unbinder) { if (this.tidy) { if (!unbinder.DeleteTempFiles()) { Console.WriteLine(DarkStrings.WAR_FailedToDeleteTempDir, unbinder.TempFilesLocation); } } else { Console.WriteLine(DarkStrings.INF_TempDirLocatedAt, unbinder.TempFilesLocation); } } } 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) { Microsoft.Tools.WindowsInstallerXml.Binder binder = new Microsoft.Tools.WindowsInstallerXml.Binder(); 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) { Assembly pyroAssembly = Assembly.GetExecutingAssembly(); Console.WriteLine("Microsoft (R) Windows Installer Xml Patch Builder Version {0}", pyroAssembly.GetName().Version.ToString()); Console.WriteLine("Copyright (C) Microsoft Corporation 2003. All rights reserved.\n"); Console.WriteLine(); } if (this.showHelp) { Console.WriteLine(" usage: pyro.exe [-?] [-nologo] inputFile -out outputFile [-t baseline wixTransform]"); Console.WriteLine(); Console.WriteLine(" -cc path to cache built cabinets"); Console.WriteLine(" -ext extension assembly or \"class, assembly\""); Console.WriteLine(" -nologo skip printing logo information"); Console.WriteLine(" -notidy do not delete temporary files (useful for debugging)"); Console.WriteLine(" -out specify output file"); Console.WriteLine(" -reusecab reuse cabinets from cabinet cache"); Console.WriteLine(" -sa suppress assemblies: do not get assembly name information for assemblies"); Console.WriteLine(" -sf suppress files: do not get any file information (equivalent to -sa and -sh)"); Console.WriteLine(" -sh suppress file info: do not get hash, version, language, etc"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -t baseline transform one or more wix transforms and its baseline"); Console.WriteLine(" -v verbose output"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -? this help information"); Console.WriteLine(); Console.WriteLine("Environment variables:"); Console.WriteLine(" WIX_TEMP overrides the temporary directory used for cab extraction, binary extraction, ..."); Console.WriteLine(); Console.WriteLine("Common extensions:"); Console.WriteLine(" .wxi - Windows installer Xml Include file"); Console.WriteLine(" .wxl - Windows installer Xml Localization file"); Console.WriteLine(" .wxs - Windows installer Xml Source file"); Console.WriteLine(" .wixlib - Windows installer Xml Library file (in XML format)"); Console.WriteLine(" .wixobj - Windows installer Xml Object file (in XML format)"); Console.WriteLine(" .wixout - Windows installer Xml Output file (in XML format)"); Console.WriteLine(); Console.WriteLine(" .msi - Windows installer Product Database"); Console.WriteLine(" .msm - Windows installer Merge Module"); Console.WriteLine(" .msp - Windows installer Patch"); Console.WriteLine(" .mst - Windows installer Transform"); Console.WriteLine(" .pcp - Windows installer Patch Creation Package"); Console.WriteLine(); Console.WriteLine("For more information see: http://wix.sourceforge.net"); return(this.messageHandler.LastErrorNumber); } // Load the extension if one was passed on the command line. WixExtension wixExtension = null; if (null != this.extension) { wixExtension = WixExtension.Load(extension); } // Load in transforms ArrayList transforms = new ArrayList(); foreach (DictionaryEntry inputTransform in inputTransforms) { Output transformOutput = Output.Load(inputTransform.Key.ToString(), false, false); PatchTransform patchTransform = new PatchTransform(transformOutput, (string)inputTransform.Value); transforms.Add(patchTransform); } // Load the patch Patch patch = new Patch(); patch.Load(this.inputFile); // Copy transforms into output if (0 < transforms.Count) { patch.AttachTransforms(transforms); } // Create and configure the binder binder = new Microsoft.Tools.WindowsInstallerXml.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; if (this.suppressFiles) { binder.SuppressAssemblies = true; binder.SuppressFileHashAndInfo = true; } // Load the extension if provided and set all its properties if (null != wixExtension) { binder.Extension = wixExtension.BinderExtension; } 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.Extension.ReuseCabinets = this.reuseCabinets; binder.Extension.CabCachePath = this.cabCachePath; binder.Extension.Output = patch.PatchOutput; // 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("Warning, failed to delete temporary directory: {0}", binder.TempFilesLocation); } } else { Console.WriteLine("Temporary directory located at '{0}'.", binder.TempFilesLocation); } } } return(this.messageHandler.LastErrorNumber); }
/// <summary> /// Extracts files from a merge module and creates corresponding ComponentGroup WiX authoring. /// </summary> private void MeltModule() { Decompiler decompiler = null; Unbinder unbinder = null; Melter melter = null; try { // create the decompiler, unbinder, and melter decompiler = new Decompiler(); unbinder = new Unbinder(); melter = new Melter(decompiler, id); // read the configuration file (melt.exe.config) AppCommon.ReadConfiguration(this.extensionList); // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); decompiler.AddExtension(wixExtension); unbinder.AddExtension(wixExtension); } // set options decompiler.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); unbinder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); unbinder.SuppressDemodularization = true; decompiler.Message += new MessageEventHandler(this.messageHandler.Display); unbinder.Message += new MessageEventHandler(this.messageHandler.Display); melter.Message += new MessageEventHandler(this.messageHandler.Display); // print friendly message saying what file is being decompiled Console.WriteLine(Path.GetFileName(this.inputFile)); // unbind Output output = unbinder.Unbind(this.inputFile, this.outputType, this.exportBasePath); if (null != output) { Wix.Wix wix = melter.Melt(output); if (null != wix) { XmlTextWriter writer = null; try { writer = new XmlTextWriter(this.outputFile, System.Text.Encoding.UTF8); writer.Indentation = 4; writer.IndentChar = ' '; writer.QuoteChar = '"'; writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); wix.OutputXml(writer); writer.WriteEndDocument(); } finally { if (null != writer) { writer.Close(); } } } } } finally { if (null != decompiler) { if (this.tidy) { if (!decompiler.DeleteTempFiles()) { Console.WriteLine(MeltStrings.WAR_FailedToDeleteTempDir, decompiler.TempFilesLocation); } } else { Console.WriteLine(MeltStrings.INF_TempDirLocatedAt, decompiler.TempFilesLocation); } } if (null != unbinder) { if (this.tidy) { if (!unbinder.DeleteTempFiles()) { Console.WriteLine(MeltStrings.WAR_FailedToDeleteTempDir, unbinder.TempFilesLocation); } } else { Console.WriteLine(MeltStrings.INF_TempDirLocatedAt, unbinder.TempFilesLocation); } } } }
/// <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) { Decompiler decompiler = null; Mutator mutator = null; Unbinder unbinder = null; 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) { Assembly darkAssembly = Assembly.GetExecutingAssembly(); Console.WriteLine("Microsoft (R) Windows Installer Xml Decompiler Version {0}", darkAssembly.GetName().Version.ToString()); Console.WriteLine("Copyright (C) Microsoft Corporation 2003. All rights reserved.\n"); Console.WriteLine(); } if (this.showHelp) { Console.WriteLine(" usage: dark.exe [-?] [-nologo] database.msi source.wxs"); Console.WriteLine(); Console.WriteLine(" -ext extension assembly or \"class, assembly\""); Console.WriteLine(" -nologo skip printing dark logo information"); Console.WriteLine(" -notidy do not delete temporary files (useful for debugging)"); Console.WriteLine(" -sdet suppress dropping empty tables (adds EnsureTable as appropriate)"); Console.WriteLine(" -sras suppress relative action sequencing (use explicit sequence numbers)"); Console.WriteLine(" -sui suppress decompiling UI-related tables"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -v verbose output"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -x <path> export binaries from cabinets and embedded binaries to the provided path"); Console.WriteLine(" -xo output xml instead of WiX source code (mandatory for transforms and patches)"); Console.WriteLine(" -? this help information"); Console.WriteLine(); Console.WriteLine("Environment variables:"); Console.WriteLine(" WIX_TEMP overrides the temporary directory used for cab extraction, binary extraction, ..."); Console.WriteLine(); Console.WriteLine("Common extensions:"); Console.WriteLine(" .wxi - Windows installer Xml Include file"); Console.WriteLine(" .wxl - Windows installer Xml Localization file"); Console.WriteLine(" .wxs - Windows installer Xml Source file"); Console.WriteLine(" .wixlib - Windows installer Xml Library file (in XML format)"); Console.WriteLine(" .wixobj - Windows installer Xml Object file (in XML format)"); Console.WriteLine(" .wixout - Windows installer Xml Output file (in XML format)"); Console.WriteLine(); Console.WriteLine(" .msi - Windows installer Product Database"); Console.WriteLine(" .msm - Windows installer Merge Module"); Console.WriteLine(" .msp - Windows installer Patch"); Console.WriteLine(" .mst - Windows installer Transform"); Console.WriteLine(" .pcp - Windows installer Patch Creation Package"); Console.WriteLine(); Console.WriteLine("For more information see: http://wix.sourceforge.net"); return(this.messageHandler.LastErrorNumber); } // create the decompiler and mutator decompiler = new Decompiler(); mutator = new Mutator(); unbinder = new Unbinder(); // read the configuration file (dark.exe.config) AppCommon.ReadConfiguration(this.extensionList); // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); decompiler.AddExtension(wixExtension); unbinder.AddExtension(wixExtension); } // set options decompiler.SuppressDroppingEmptyTables = this.suppressDroppingEmptyTables; decompiler.SuppressRelativeActionSequencing = this.suppressRelativeActionSequencing; decompiler.SuppressUI = this.suppressUI; decompiler.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); unbinder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); decompiler.Message += new MessageEventHandler(this.messageHandler.Display); mutator.Message += new MessageEventHandler(this.messageHandler.Display); unbinder.Message += new MessageEventHandler(this.messageHandler.Display); // print friendly message saying what file is being decompiled Console.WriteLine(Path.GetFileName(this.inputFile)); // unbind Output output = unbinder.Unbind(this.inputFile, this.outputType, this.exportBasePath); if (null != output) { if (OutputType.Patch == this.outputType || OutputType.Transform == this.outputType || this.outputXml) { output.Save(this.outputFile, null, new WixVariableResolver(), null); } else // decompile { Wix.Wix wix = decompiler.Decompile(output); // output if (null != wix) { XmlTextWriter writer = null; // mutate the Wix document if (!mutator.Mutate(wix)) { return(this.messageHandler.LastErrorNumber); } try { writer = new XmlTextWriter(this.outputFile, System.Text.Encoding.UTF8); writer.Indentation = 4; writer.IndentChar = ' '; writer.QuoteChar = '"'; writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); wix.OutputXml(writer); writer.WriteEndDocument(); } finally { if (null != writer) { writer.Close(); } } } } } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } finally { if (null != decompiler) { if (this.tidy) { if (!decompiler.DeleteTempFiles()) { Console.WriteLine("Warning, failed to delete temporary directory: {0}", decompiler.TempFilesLocation); } } else { Console.WriteLine("Temporary directory located at '{0}'.", decompiler.TempFilesLocation); } } if (null != unbinder) { if (this.tidy) { if (!unbinder.DeleteTempFiles()) { Console.WriteLine("Warning, failed to delete temporary directory: {0}", unbinder.TempFilesLocation); } } else { Console.WriteLine("Temporary directory located at '{0}'.", unbinder.TempFilesLocation); } } } 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 Microsoft.Tools.WindowsInstallerXml.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.AllowEmptyTransforms = this.allowEmptyTransforms; 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); }
/// <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 (0 == this.inputFiles.Count) { this.showHelp = true; } if (this.showLogo) { Assembly assembly = Assembly.GetExecutingAssembly(); Console.WriteLine("Microsoft (R) Windows Installer Xml Validator version {0}", assembly.GetName().Version.ToString()); Console.WriteLine("Copyright (C) Microsoft Corporation 2003. All rights reserved."); Console.WriteLine(); } if (this.showHelp) { Console.WriteLine(" usage: smoke.exe [-?] databaseFile [databaseFile ...]"); Console.WriteLine(); Console.WriteLine(" -cub additional .cub file containing ICEs to run"); Console.WriteLine(" -ext extension assembly or \"class, assembly\""); Console.WriteLine(" -nodefault do not add the default .cub files for .msi and .msm files"); Console.WriteLine(" -nologo skip printing smoke logo information"); Console.WriteLine(" -notidy do not delete temporary files (useful for debugging)"); Console.WriteLine(" -sice:<ICE> suppress an internal consistency evaluator (ICE)"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -v verbose output"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -? this help information"); Console.WriteLine(); Console.WriteLine("Environment variables:"); Console.WriteLine(" WIX_TEMP overrides the temporary directory used for validation"); Console.WriteLine(); Console.WriteLine("For more information see: http://wix.sourceforge.net"); return(this.messageHandler.LastErrorNumber); } validator.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); // load any extensions bool validatorExtensionLoaded = false; foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); ValidatorExtension validatorExtension = wixExtension.ValidatorExtension; if (null != validatorExtension) { if (validatorExtensionLoaded) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "cannot load linker extension: {0}. light can only load one link extension and has already loaded link extension: {1}.", validatorExtension.GetType().ToString(), validator.Extension.ToString()), "ext"); } validator.Extension = validatorExtension; validatorExtensionLoaded = true; } } // set the message handlers validator.Extension.Message += new MessageEventHandler(this.messageHandler.Display); // disable ICE33 by default this.suppressICEs.Add("ICE33"); // set the suppressed ICEs string[] suppressICEArray = new string[this.suppressICEs.Count]; this.suppressICEs.CopyTo(suppressICEArray, 0); validator.SuppressedICEs = suppressICEArray; foreach (string inputFile in this.inputFiles) { // set the default cube file Assembly assembly = Assembly.GetExecutingAssembly(); string appDirectory = Path.GetDirectoryName(assembly.Location); if (this.addDefault) { switch (Path.GetExtension(inputFile).ToLower(CultureInfo.InvariantCulture)) { case ".msm": validator.AddCubeFile(Path.Combine(appDirectory, "mergemod.cub")); break; case ".msi": validator.AddCubeFile(Path.Combine(appDirectory, "darice.cub")); break; default: throw new Exception("Unknown input file format - expected a .msi or .msm file."); } } // print friendly message saying what file is being validated Console.WriteLine(Path.GetFileName(inputFile)); try { validator.Validate(Path.GetFullPath(inputFile)); } finally { if (this.tidy) { if (!validator.DeleteTempFiles()) { Console.WriteLine("Warning, failed to delete temporary directory: {0}", validator.TempFilesLocation); } } else { Console.WriteLine("Temporary directory located at '{0}'.", validator.TempFilesLocation); } } } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } 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 (0 == this.sourceFiles.Count) { this.showHelp = true; } else if (1 < this.sourceFiles.Count && null != this.outputFile) { throw new ArgumentException("cannot specify more than one source file with single output file. Either specify an output directory for the -out argument by ending the argument with a '\\' or remove the -out argument to have the source files compiled to the current directory.", "-out"); } if (this.showLogo) { Assembly candleAssembly = Assembly.GetExecutingAssembly(); Console.WriteLine("Microsoft (R) Windows Installer Xml Compiler version {0}", candleAssembly.GetName().Version.ToString()); Console.WriteLine("Copyright (C) Microsoft Corporation 2003. All rights reserved."); Console.WriteLine(); } if (this.showHelp) { Console.WriteLine(" usage: candle.exe [-?] [-nologo] [-out outputFile] sourceFile [sourceFile ...]"); Console.WriteLine(); Console.WriteLine(" -d<name>=<value> define a parameter for the preprocessor"); Console.WriteLine(" -p<file> preprocess to a file (or stdout if no file supplied)"); Console.WriteLine(" -I<dir> add to include search path"); Console.WriteLine(" -nologo skip printing candle logo information"); Console.WriteLine(" -out specify output file (default: write to current directory)"); Console.WriteLine(" -pedantic show pedantic messages"); Console.WriteLine(" -ss suppress schema validation of documents (performance boost)"); Console.WriteLine(" -trace show source trace for errors, warnings, and verbose messages"); Console.WriteLine(" -ext extension assembly or \"class, assembly\""); Console.WriteLine(" -zs only do validation of documents (no output)"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -v verbose output"); Console.WriteLine(" -? this help information"); Console.WriteLine(); Console.WriteLine("Common extensions:"); Console.WriteLine(" .wxs - Windows installer Xml Source file"); Console.WriteLine(" .wxi - Windows installer Xml Include file"); Console.WriteLine(" .wxl - Windows installer Xml Localization file"); Console.WriteLine(" .wixobj - Windows installer Xml Object file (in XML format)"); Console.WriteLine(" .wixlib - Windows installer Xml Library file (in XML format)"); Console.WriteLine(" .wixout - Windows installer Xml Output file (in XML format)"); Console.WriteLine(); Console.WriteLine(" .msm - Windows installer Merge Module"); Console.WriteLine(" .msi - Windows installer Product Database"); Console.WriteLine(" .msp - Windows installer Patch"); Console.WriteLine(" .mst - Windows installer Transform"); Console.WriteLine(" .pcp - Windows installer Patch Creation Package"); Console.WriteLine(); Console.WriteLine("For more information see: http://wix.sourceforge.net"); return(this.messageHandler.LastErrorNumber); } // create the preprocessor and compiler Preprocessor preprocessor = new Preprocessor(); preprocessor.Message += new MessageEventHandler(this.messageHandler.Display); for (int i = 0; i < this.includeSearchPaths.Count; ++i) { preprocessor.IncludeSearchPaths.Add(this.includeSearchPaths[i]); } Compiler compiler = new Compiler(); compiler.Message += new MessageEventHandler(this.messageHandler.Display); compiler.ShowPedanticMessages = this.showPedanticMessages; compiler.SuppressValidate = this.suppressSchema; // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); preprocessor.AddExtension(wixExtension); compiler.AddExtension(wixExtension); } // preprocess then compile each source file foreach (string sourceFile in this.sourceFiles) { string sourceFileName = Path.GetFileName(sourceFile); string targetFile; if (null != this.outputFile) { targetFile = this.outputFile; } else if (null != this.outputDirectory) { targetFile = Path.Combine(this.outputDirectory, Path.ChangeExtension(sourceFileName, ".wixobj")); } else { targetFile = Path.ChangeExtension(sourceFileName, ".wixobj"); } // print friendly message saying what file is being compiled Console.WriteLine(sourceFileName); // preprocess the source XmlDocument sourceDocument; try { if (this.preprocessToStdout) { preprocessor.PreprocessOut = Console.Out; } else if (null != this.preprocessFile) { preprocessor.PreprocessOut = new StreamWriter(this.preprocessFile); } sourceDocument = preprocessor.Process(Path.GetFullPath(sourceFile), this.parameters); } finally { if (null != preprocessor.PreprocessOut && Console.Out != preprocessor.PreprocessOut) { preprocessor.PreprocessOut.Close(); } } // if we're not actually going to compile anything, move on to the next file if (this.schemaOnly || null == sourceDocument || this.preprocessToStdout || null != this.preprocessFile) { continue; } // and now we do what we came here to do... Intermediate intermediate = compiler.Compile(sourceDocument); // save the intermediate to disk if no errors were found for this source file if (null != intermediate) { intermediate.Save(targetFile); } } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } 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) { Microsoft.Tools.WindowsInstallerXml.Binder binder = null; Linker linker = null; Localizer localizer = null; SectionCollection sections = new SectionCollection(); ArrayList transforms = new ArrayList(); 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 (0 == this.inputFiles.Count) { this.showHelp = true; } else if (null == this.outputFile) { if (1 < this.inputFiles.Count) { throw new ArgumentException("must specify output file when using more than one input file", "-out"); } this.outputFile = Path.ChangeExtension(Path.GetFileName(this.inputFiles[0]), ".wix"); // we'll let the linker change the extension later } if (this.showLogo) { Assembly lightAssembly = Assembly.GetExecutingAssembly(); Console.WriteLine("Microsoft (R) Windows Installer Xml Linker version {0}", lightAssembly.GetName().Version.ToString()); Console.WriteLine("Copyright (C) Microsoft Corporation 2003. All rights reserved."); Console.WriteLine(); } if (this.showHelp) { Console.WriteLine(" usage: light.exe [-?] [-b basePath] [-nologo] [-out outputFile] objectFile [objectFile ...]"); Console.WriteLine(); Console.WriteLine(" -ai allow identical rows, identical rows will be treated as a warning"); Console.WriteLine(" -au (experimental) allow unresolved references, will not create a valid output"); Console.WriteLine(" -b base path to locate all files (default: current directory)"); Console.WriteLine(" -bf bind files into a wixout (only valid with -xo option)"); Console.WriteLine(" -cc path to cache built cabinets (will not be deleted after linking)"); Console.WriteLine(" -ct <N> number of threads to use when creating cabinets (default: %NUMBER_OF_PROCESSORS%)"); Console.WriteLine(" -cultures:<cultures> semicolon-delimited list of localized string cultures to load from libraries"); Console.WriteLine(" -cub additional .cub file containing ICEs to run"); Console.WriteLine(" -d<name>=<value> define a wix variable"); Console.WriteLine(" -ext extension assembly or \"class, assembly\""); Console.WriteLine(" -fv add a 'fileVersion' entry to the MsiAssemblyName table (rarely needed)"); Console.WriteLine(" -loc <loc.wxl> read localization strings from .wxl file"); Console.WriteLine(" -nologo skip printing light logo information"); Console.WriteLine(" -notidy do not delete temporary files (useful for debugging)"); Console.WriteLine(" -out specify output file (default: write to current directory)"); Console.WriteLine(" -pedantic show pedantic messages"); Console.WriteLine(" -reusecab reuse cabinets from cabinet cache"); Console.WriteLine(" -sa suppress assemblies: do not get assembly name information for assemblies"); Console.WriteLine(" -sacl suppress resetting ACLs (useful when laying out image to a network share)"); Console.WriteLine(" -sadmin suppress default admin sequence actions"); Console.WriteLine(" -sadv suppress default adv sequence actions"); Console.WriteLine(" -sdut suppress dropping unreal tables to the output image (default with -xo)"); Console.WriteLine(" -sice:<ICE> suppress an internal consistency evaluator (ICE)"); Console.WriteLine(" -sma suppress processing the data in MsiAssembly table"); Console.WriteLine(" -sf suppress files: do not get any file information (equivalent to -sa and -sh)"); Console.WriteLine(" -sh suppress file info: do not get hash, version, language, etc"); Console.WriteLine(" -sl suppress layout"); Console.WriteLine(" -ss suppress schema validation of documents (performance boost)"); Console.WriteLine(" -sui suppress default UI sequence actions"); Console.WriteLine(" -sv suppress intermediate file version mismatch checking"); Console.WriteLine(" -sval suppress MSI/MSM validation"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -ts tag sectionId attribute on rows (default with -xo)"); Console.WriteLine(" -tsa tag sectionId attribute on rows, generating when null (default with -xo)"); Console.WriteLine(" -usf <output.xml> unreferenced symbols file"); Console.WriteLine(" -v verbose output"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -xo output xml instead of MSI format"); Console.WriteLine(" -? this help information"); Console.WriteLine(); Console.WriteLine("Environment variables:"); Console.WriteLine(" WIX_TEMP overrides the temporary directory used for cab creation, msm exploding, ..."); Console.WriteLine(); Console.WriteLine("Common extensions:"); Console.WriteLine(" .wxi - Windows installer Xml Include file"); Console.WriteLine(" .wxl - Windows installer Xml Localization file"); Console.WriteLine(" .wxs - Windows installer Xml Source file"); Console.WriteLine(" .wixlib - Windows installer Xml Library file (in XML format)"); Console.WriteLine(" .wixobj - Windows installer Xml Object file (in XML format)"); Console.WriteLine(" .wixout - Windows installer Xml Output file (in XML format)"); Console.WriteLine(); Console.WriteLine(" .msi - Windows installer Product Database"); Console.WriteLine(" .msm - Windows installer Merge Module"); Console.WriteLine(" .msp - Windows installer Patch"); Console.WriteLine(" .mst - Windows installer Transform"); Console.WriteLine(" .pcp - Windows installer Patch Creation Package"); Console.WriteLine(); Console.WriteLine("For more information see: http://wix.sourceforge.net"); return(this.messageHandler.LastErrorNumber); } // create the linker, binder, and validator linker = new Linker(); binder = new Microsoft.Tools.WindowsInstallerXml.Binder(); linker.AllowIdenticalRows = this.allowIdenticalRows; linker.AllowUnresolvedReferences = this.allowUnresolvedReferences; linker.Cultures = this.cultures; linker.UnreferencedSymbolsFile = this.unreferencedSymbolsFile; linker.ShowPedanticMessages = this.showPedanticMessages; linker.SuppressDroppingUnrealTables = this.suppressDroppingUnrealTables; linker.SuppressMsiAssemblyTable = this.suppressMsiAssemblyTable; linker.WixVariableResolver = this.wixVariableResolver; // set the sequence suppression options linker.SuppressAdminSequence = this.suppressAdminSequence; linker.SuppressAdvertiseSequence = this.suppressAdvertiseSequence; linker.SuppressUISequence = this.suppressUISequence; linker.SectionIdOnRows = this.sectionIdOnRows; linker.GenerateSectionIds = this.generateSectionIds; // default the number of cabbing threads to the number of processors if it wasn't specified if (0 == this.cabbingThreadCount) { string numberOfProcessors = System.Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS"); try { if (null != numberOfProcessors) { this.cabbingThreadCount = Convert.ToInt32(numberOfProcessors, CultureInfo.InvariantCulture.NumberFormat); if (0 >= this.cabbingThreadCount) { throw new WixException(WixErrors.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors)); } } else // default to 1 if the environment variable is not set { this.cabbingThreadCount = 1; } } catch (ArgumentException) { throw new WixException(WixErrors.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors)); } catch (FormatException) { throw new WixException(WixErrors.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors)); } } binder.CabbingThreadCount = this.cabbingThreadCount; binder.SuppressAclReset = this.suppressAclReset; binder.SetMsiAssemblyNameFileVersion = this.setMsiAssemblyNameFileVersion; binder.SuppressAssemblies = this.suppressAssemblies; binder.SuppressFileHashAndInfo = this.suppressFileHashAndInfo; if (this.suppressFiles) { binder.SuppressAssemblies = true; binder.SuppressFileHashAndInfo = true; } binder.SuppressLayout = this.suppressLayout; binder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); binder.WixVariableResolver = this.wixVariableResolver; validator.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); 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); } } if (null != this.basePaths) { foreach (string basePath in this.basePaths) { this.sourcePaths.Add(basePath); } } // load any extensions bool binderExtensionLoaded = false; bool validatorExtensionLoaded = false; foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); linker.AddExtension(wixExtension); if (null != wixExtension.BinderExtension) { if (binderExtensionLoaded) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "cannot load binder extension: {0}. light can only load one binder extension and has already loaded binder extension: {1}.", wixExtension.BinderExtension.GetType().ToString(), binder.Extension.ToString()), "ext"); } binder.Extension = wixExtension.BinderExtension; binderExtensionLoaded = true; } ValidatorExtension validatorExtension = wixExtension.ValidatorExtension; if (null != validatorExtension) { if (validatorExtensionLoaded) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "cannot load linker extension: {0}. light can only load one link extension and has already loaded link extension: {1}.", validatorExtension.GetType().ToString(), validator.Extension.ToString()), "ext"); } validator.Extension = validatorExtension; validatorExtensionLoaded = true; } } // set the message handlers linker.Message += new MessageEventHandler(this.messageHandler.Display); binder.Message += new MessageEventHandler(this.messageHandler.Display); validator.Extension.Message += new MessageEventHandler(this.messageHandler.Display); Output output = null; // instantiate the localizer and load any localization files if (0 < this.localizationFiles.Count || null != this.cultures || !this.outputXml) { localizer = new Localizer(); localizer.Message += new MessageEventHandler(this.messageHandler.Display); // load each localization file foreach (string localizationFile in this.localizationFiles) { Localization localization = Localization.Load(localizationFile, linker.TableDefinitions, this.suppressSchema); localizer.AddLocalization(localization); } // immediately stop processing if any errors were found if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } } // loop through all the believed object files foreach (string inputFile in this.inputFiles) { string dirName = Path.GetDirectoryName(inputFile); string inputFileFullPath = Path.GetFullPath(inputFile); if (!this.sourcePaths.Contains(dirName)) { this.sourcePaths.Add(dirName); } // try loading as an object file try { Intermediate intermediate = Intermediate.Load(inputFileFullPath, linker.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); sections.AddRange(intermediate.Sections); continue; // next file } catch (WixNotIntermediateException) { // try another format } // try loading as a library file try { Library library = Library.Load(inputFileFullPath, linker.TableDefinitions, this.suppressVersionCheck, this.suppressSchema); sections.AddRange(library.Sections); // load the localization files for the selected cultures if (null != this.cultures) { Localization localization = library.GetLocalization(this.cultures); if (null != localization) { localizer.AddLocalization(localization); } } continue; // next file } catch (WixNotLibraryException) { // try another format } // try loading as an output file output = Output.Load(inputFileFullPath, this.suppressVersionCheck, this.suppressSchema); } // immediately stop processing if any errors were found if (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } // set the binder extension information foreach (string basePath in this.basePaths) { binder.Extension.BasePaths.Add(basePath); } binder.Extension.CabCachePath = this.cabCachePath; binder.Extension.ReuseCabinets = this.reuseCabinets; foreach (string sourcePath in this.sourcePaths) { binder.Extension.SourcePaths.Add(sourcePath); } // and now for the fun part if (null == output) { // tell the linker about the localizer linker.Localizer = localizer; localizer = null; output = linker.Link(sections, transforms); // if an error occurred during linking, stop processing if (null == output) { return(this.messageHandler.LastErrorNumber); } } else if (0 != sections.Count) { throw new InvalidOperationException("Cannot link object files (.wixobj) files with an output file (.wixout)"); } // Now that the output object is either linked or loaded, tell the binder extension about it. binder.Extension.Output = output; // only output the xml if its a patch build or user specfied to only output wixout if (this.outputXml || OutputType.Patch == output.Type) { string outputExtension = Path.GetExtension(this.outputFile); if (null == outputExtension || 0 == outputExtension.Length || ".wix" == outputExtension) { if (OutputType.Patch == output.Type) { this.outputFile = Path.ChangeExtension(this.outputFile, ".wixmsp"); } else { this.outputFile = Path.ChangeExtension(this.outputFile, ".wixout"); } } output.Save(this.outputFile, (this.bindFiles ? binder.Extension : null), this.wixVariableResolver, binder.TempFilesLocation); } else // finish creating the MSI/MSM { string outputExtension = Path.GetExtension(this.outputFile); if (null == outputExtension || 0 == outputExtension.Length || ".wix" == outputExtension) { if (OutputType.Module == output.Type) { this.outputFile = Path.ChangeExtension(this.outputFile, ".msm"); } else if (OutputType.PatchCreation == output.Type) { this.outputFile = Path.ChangeExtension(this.outputFile, ".pcp"); } else { this.outputFile = Path.ChangeExtension(this.outputFile, ".msi"); } } // tell the binder about the localizer binder.Localizer = localizer; // tell the binder about the validator if validation isn't suppressed if (!this.suppressValidation && (OutputType.Module == output.Type || OutputType.Product == output.Type)) { // set the default cube file Assembly lightAssembly = Assembly.GetExecutingAssembly(); string lightDirectory = Path.GetDirectoryName(lightAssembly.Location); if (OutputType.Module == output.Type) { validator.AddCubeFile(Path.Combine(lightDirectory, "mergemod.cub")); } else // product { validator.AddCubeFile(Path.Combine(lightDirectory, "darice.cub")); } // disable ICE33 by default this.suppressICEs.Add("ICE33"); // set the suppressed ICEs string[] suppressICEArray = new string[this.suppressICEs.Count]; this.suppressICEs.CopyTo(suppressICEArray, 0); validator.SuppressedICEs = suppressICEArray; binder.Validator = validator; } binder.Bind(output, 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("Warning, failed to delete temporary directory: {0}", binder.TempFilesLocation); } } else { Console.WriteLine("Binder temporary directory located at '{0}'.", binder.TempFilesLocation); } } if (null != validator) { if (this.tidy) { if (!validator.DeleteTempFiles()) { Console.WriteLine("Warning, failed to delete temporary directory: {0}", validator.TempFilesLocation); } } else { Console.WriteLine("Validator temporary directory located at '{0}'.", validator.TempFilesLocation); } } } return(this.messageHandler.LastErrorNumber); }