public void IncludeSourceLineNumbersPreserved() { var folder = TestData.Get(@"TestData\IncludePath"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var result = WixRunner.Execute(warningsAsErrors: false, new[] { "build", Path.Combine(folder, "Package.wxs"), Path.Combine(folder, "PackageComponents.wxs"), "-loc", Path.Combine(folder, "Package.en-us.wxl"), "-includepath", Path.Combine(folder, "data"), "-bindpath", Path.Combine(folder, "data"), "-intermediateFolder", intermediateFolder, "-o", Path.Combine(baseFolder, @"bin\test.msi") }); result.AssertSuccess(); using (var output = WixOutput.Read(Path.Combine(baseFolder, @"bin\test.wixpdb"))) { var intermediate = Intermediate.Load(output); var component = intermediate.Sections.Single().Symbols.OfType <ComponentSymbol>().Single(); Assert.Equal(3, component.SourceLineNumbers.LineNumber); Assert.Equal(5, component.SourceLineNumbers.Parent.LineNumber); var encoded = component.SourceLineNumbers.GetEncoded(); var decoded = SourceLineNumber.CreateFromEncoded(encoded); Assert.Equal(3, decoded.LineNumber); Assert.Equal(5, decoded.Parent.LineNumber); } } }
public void CanGetDuplicateDir() { var folder = TestData.Get(@"TestData"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var msiPath = Path.Combine(baseFolder, @"bin\test.msi"); var result = WixRunner.Execute(new[] { "build", "-arch", "x64", Path.Combine(folder, "DuplicateDir", "DuplicateDir.wxs"), Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"), "-bindpath", Path.Combine(folder, "SingleFile", "data"), "-intermediateFolder", intermediateFolder, "-o", msiPath }); result.AssertSuccess(); var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb")); var section = intermediate.Sections.Single(); var dirSymbols = section.Symbols.OfType <WixToolset.Data.Symbols.DirectorySymbol>().ToList(); Assert.Equal(new[] { "dirZsSsu81KcG46xXTwc4mTSZO5Zx4", "INSTALLFOLDER", "ProgramFiles6432Folder", "ProgramFiles64Folder", "TARGETDIR" }, dirSymbols.Select(d => d.Id.Id).ToArray()); } }
private void EvaluateSourceFiles(IEnumerable <SourceFile> sourceFiles, ITupleDefinitionCreator creator, out List <SourceFile> codeFiles, out Intermediate wixipl) { codeFiles = new List <SourceFile>(); wixipl = null; foreach (var sourceFile in sourceFiles) { var extension = Path.GetExtension(sourceFile.SourcePath); if (wixipl != null || ".wxs".Equals(extension, StringComparison.OrdinalIgnoreCase)) { codeFiles.Add(sourceFile); } else { try { wixipl = Intermediate.Load(sourceFile.SourcePath, creator); } catch (WixException) { // We'll assume anything that isn't a valid intermediate is source code to compile. codeFiles.Add(sourceFile); } } } if (wixipl == null && codeFiles.Count == 0) { this.Messaging.Write(ErrorMessages.NoSourceFiles()); } else if (wixipl != null && codeFiles.Count != 0) { this.Messaging.Write(ErrorMessages.WixiplSourceFileIsExclusive()); } }
public void CanBuildSingleExeRemotePayloadBundle() { var folder = TestData.Get(@"TestData"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var exePath = Path.Combine(baseFolder, @"bin\test.exe"); var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb"); var result = WixRunner.Execute(new[] { "build", Path.Combine(folder, "SingleExeBundle", "SingleExeRemotePayload.wxs"), Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"), "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), "-intermediateFolder", intermediateFolder, "-o", exePath, }); result.AssertSuccess(); Assert.True(File.Exists(exePath)); Assert.True(File.Exists(pdbPath)); using (var wixOutput = WixOutput.Read(pdbPath)) { var intermediate = Intermediate.Load(wixOutput); var section = intermediate.Sections.Single(); var payloadSymbol = section.Symbols.OfType <WixBundlePayloadSymbol>().Where(x => x.Id.Id == "NetFx462Web").Single(); Assert.Equal(Int64.MaxValue, payloadSymbol.FileSize); } } }
public void CanBuildWithIncludePath() { var folder = TestData.Get(@"TestData\IncludePath"); var bindpath = Path.Combine(folder, "data"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var result = WixRunner.Execute(new[] { "build", Path.Combine(folder, "Package.wxs"), Path.Combine(folder, "PackageComponents.wxs"), "-loc", Path.Combine(folder, "Package.en-us.wxl"), "-bindpath", bindpath, "-intermediateFolder", intermediateFolder, "-o", Path.Combine(baseFolder, @"bin\test.msi"), "-i", bindpath, }, out var messages); Assert.Equal(0, result); Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi"))); Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb"))); Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\MsiPackage\test.txt"))); var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wir")); var section = intermediate.Sections.Single(); var wixFile = section.Tuples.OfType <WixFileTuple>().Single(); Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); } }
public void CanGet64bitProgramFiles6432Folder() { var folder = TestData.Get(@"TestData"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var msiPath = Path.Combine(baseFolder, @"bin\test.msi"); var result = WixRunner.Execute(new[] { "build", "-arch", "x64", Path.Combine(folder, "Directory", "Empty.wxs"), Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"), "-bindpath", Path.Combine(folder, "SingleFile", "data"), "-intermediateFolder", intermediateFolder, "-o", msiPath }); result.AssertSuccess(); var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb")); var section = intermediate.Sections.Single(); var dirSymbols = section.Symbols.OfType <WixToolset.Data.Symbols.DirectorySymbol>().ToList(); Assert.Equal(new[] { "INSTALLFOLDER:ProgramFiles6432Folder:MsiPackage", "ProgramFiles6432Folder:ProgramFiles64Folder:.", "ProgramFiles64Folder:TARGETDIR:PFiles64", "TARGETDIR::SourceDir" }, dirSymbols.OrderBy(d => d.Id.Id).Select(d => d.Id.Id + ":" + d.ParentDirectoryRef + ":" + d.Name).ToArray()); } }
public void CanBuildWithOverridableActions() { var folder = TestData.Get(@"TestData\OverridableActions"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var result = WixRunner.Execute(new[] { "build", "-sw1008", // this is expected for this test Path.Combine(folder, "Package.wxs"), Path.Combine(folder, "PackageComponents.wxs"), "-loc", Path.Combine(folder, "Package.en-us.wxl"), "-bindpath", Path.Combine(folder, "data"), "-intermediateFolder", intermediateFolder, "-o", Path.Combine(baseFolder, @"bin\test.msi") }); result.AssertSuccess(); Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi"))); Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb"))); Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\MsiPackage\test.txt"))); var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb")); var section = intermediate.Sections.Single(); var actions = section.Symbols.OfType <WixActionSymbol>().Where(wat => wat.Action.StartsWith("Set")).ToList(); Assert.Equal(2, actions.Count); //Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileSymbolFields.Source].AsPath().Path); //Assert.Equal(@"test.txt", wixFile[WixFileSymbolFields.Source].PreviousValue.AsPath().Path); } }
/// <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 { XmlSchemaCollection objectSchema = new XmlSchemaCollection(); FileInfo currentFile = null; ArrayList intermediates = new ArrayList(); Linker linker = null; Microsoft.Tools.WindowsInstallerXml.Binder binder = null; Localizer localizer = 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.FoundError) { return(this.messageHandler.PostProcess()); } if (0 == this.objectFiles.Count) { this.showHelp = true; } else if (null == this.outputFile) { if (1 < this.objectFiles.Count) { throw new ArgumentException("must specify output file when using more than one input file", "-out"); } FileInfo fi = (FileInfo)this.objectFiles[0]; this.outputFile = new FileInfo(Path.ChangeExtension(fi.Name, ".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(" -cc path to cache built cabinets (will not be deleted after linking)"); Console.WriteLine(" -ext extension (class, assembly), should extend SchemaExtension or BinderExtension"); Console.WriteLine(" -fv add a 'fileVersion' entry to the MsiAssemblyName table (rarely needed)"); Console.WriteLine(" -i specify the base output path for uncompressed images (default: -out parameter)"); Console.WriteLine(" -loc read localization string sfrom .wxl file"); Console.WriteLine(" -nologo skip printing light logo information"); Console.WriteLine(" -notidy do not delete temporary files (useful for debugging)"); Console.WriteLine(" -reusecab reuse cabinets from cabinet cache"); Console.WriteLine(" -out specify output file (default: write to current directory)"); Console.WriteLine(" -xo output xml instead of MSI format"); Console.WriteLine(" -pedantic:<level> pedantic checks (levels: easy, heroic, legendary)"); 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(" -sa suppress assemblys: 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(" -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(" -ts tag sectionId attribute on tuples (ignored if not used with -xo)"); Console.WriteLine(" -ust use small table definitions (for backwards compatiblity)"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -w<N> set the warning level (0: show all, 3: show none)"); Console.WriteLine(" -sw suppress all warnings (same as -w3)"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -v verbose output (same as -v2)"); Console.WriteLine(" -v<N> sets the level of verbose output (0: most output, 3: none)"); 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(" .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(" .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.PostProcess()); } // create the linker and the binder linker = new Linker(this.useSmallTables); binder = new Microsoft.Tools.WindowsInstallerXml.Binder(this.useSmallTables); linker.AllowIdenticalRows = this.allowIdenticalRows; linker.AllowUnresolvedReferences = this.allowUnresolvedReferences; linker.PedanticLevel = this.pedanticLevel; // set the sequence suppression options linker.SuppressAdminSequence = this.suppressAdminSequence; linker.SuppressAdvertiseSequence = this.suppressAdvertiseSequence; linker.SuppressUISequence = this.suppressUISequence; linker.SectionIdOnTuples = this.sectionIdOnTuples; 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"); 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; foreach (string extension in this.extensionList) { Type extensionType = Type.GetType(extension); if (null == extensionType) { throw new WixInvalidExtensionException(extension); } if (extensionType.IsSubclassOf(typeof(BinderExtension))) { object[] extensionArgs = new object[] { this.basePaths, this.cabCachePath, this.reuseCabinets, this.sourcePaths }; BinderExtension binderExtension = Activator.CreateInstance(extensionType, extensionArgs) as BinderExtension; Debug.Assert(null != 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}.", binderExtension.ToString(), binder.Extension.ToString()), "ext"); } binder.Extension = binderExtension; binderExtensionLoaded = true; } else if (extensionType.IsSubclassOf(typeof(SchemaExtension))) { linker.AddExtension((SchemaExtension)Activator.CreateInstance(extensionType)); } else { throw new WixInvalidExtensionException(extension, extensionType, typeof(BinderExtension), typeof(SchemaExtension)); } } // if the binder extension has not been loaded yet use the built-in binder extension if (!binderExtensionLoaded) { binder.Extension = new LightBinderExtension(this.basePaths, this.cabCachePath, this.reuseCabinets, this.sourcePaths); } if (null != this.imagebaseOutputPath) { binder.ImageBaseOutputPath = this.imagebaseOutputPath; } // set the message handlers linker.Message += new MessageEventHandler(this.messageHandler.Display); binder.Message += new MessageEventHandler(this.messageHandler.Display); // load the object schema if (!this.suppressSchema) { Assembly wixAssembly = Assembly.Load("wix"); using (Stream objectsSchemaStream = wixAssembly.GetManifestResourceStream("Microsoft.Tools.WindowsInstallerXml.Xsd.objects.xsd")) { XmlReader reader = new XmlTextReader(objectsSchemaStream); objectSchema.Add("http://schemas.microsoft.com/wix/2003/04/objects", reader); } } Output output = null; // loop through all the believed object files foreach (FileInfo objectFile in this.objectFiles) { currentFile = objectFile; string dirName = Path.GetDirectoryName(currentFile.FullName); if (!StringArrayContains(this.sourcePaths, dirName)) { this.sourcePaths.Add(dirName); } // load the object file into an intermediate object and add it to the list to be linked using (Stream fileStream = new FileStream(currentFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { XmlReader fileReader = new XmlTextReader(fileStream); try { XmlReader intermediateReader = fileReader; if (!this.suppressSchema) { intermediateReader = new XmlValidatingReader(fileReader); ((XmlValidatingReader)intermediateReader).Schemas.Add(objectSchema); } Intermediate intermediate = Intermediate.Load(intermediateReader, currentFile.FullName, linker.TableDefinitions, this.suppressVersionCheck); intermediates.Add(intermediate); continue; // next file } catch (WixNotIntermediateException) { // try another format } try { Library library = Library.Load(currentFile.FullName, linker.TableDefinitions, this.suppressVersionCheck); intermediates.AddRange(library.Intermediates); continue; // next file } catch (WixNotLibraryException) { // try another format } output = Output.Load(currentFile.FullName, this.suppressVersionCheck); } } // instantiate the localizer and load any wixloc files if (0 < this.localizationFiles.Count || !this.outputXml) { localizer = new Localizer(); localizer.Message += new MessageEventHandler(this.messageHandler.Display); // load each wixloc file foreach (string localizationFile in this.localizationFiles) { localizer.LoadFromFile(localizationFile); } // immediately stop processing if any errors were found if (this.messageHandler.FoundError) { return(this.messageHandler.PostProcess()); } } // and now for the fun part currentFile = this.outputFile; if (null == output) { // tell the linker about the localizer linker.Localizer = localizer; localizer = null; output = linker.Link((Intermediate[])intermediates.ToArray(typeof(Intermediate))); // if an error occurred during linking, stop processing if (null == output) { return(this.messageHandler.PostProcess()); } } else if (0 != intermediates.Count) { throw new InvalidOperationException("Cannot link object files (.wixobj) files with an output file (.wixout)"); } output.Path = this.outputFile.FullName; // only output the xml if (this.outputXml) { string outputExtension = Path.GetExtension(this.outputFile.FullName); if (null == outputExtension || 0 == outputExtension.Length || ".wix" == outputExtension) { output.Path = Path.ChangeExtension(this.outputFile.FullName, ".wixout"); } output.Save(); } else // finish creating the MSI/MSM { string outputExtension = Path.GetExtension(this.outputFile.FullName); if (null == outputExtension || 0 == outputExtension.Length || ".wix" == outputExtension) { if (OutputType.Module == output.Type) { output.Path = Path.ChangeExtension(this.outputFile.FullName, ".msm"); } else if (OutputType.PatchCreation == output.Type) { output.Path = Path.ChangeExtension(this.outputFile.FullName, ".pcp"); } else { output.Path = Path.ChangeExtension(this.outputFile.FullName, ".msi"); } } // tell the binder about the localizer binder.Localizer = localizer; binder.Bind(output); } currentFile = null; } catch (WixInvalidIdtException) { this.tidy = false; // make sure the IDT files stay around throw; } catch (WixMergeFailureException) { this.tidy = false; // make sure the merge.log stays around 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); } } } } catch (WixException we) { // TODO: once all WixExceptions are converted to errors, this clause // should be a no-op that just catches WixFatalErrorException's this.messageHandler.Display("light.exe", "LGHT", we); return(1); } catch (Exception e) { this.OnMessage(WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } return(this.messageHandler.PostProcess()); }
public void CanSaveAndLoadMultipleIntermediateWithCustomDefinitionsAndTags() { var sln = new SourceLineNumber("test.wxs", 1); // Intermediate #1 var fieldDefs = new[] { new IntermediateFieldDefinition("A", IntermediateFieldType.String), new IntermediateFieldDefinition("B", IntermediateFieldType.Number), new IntermediateFieldDefinition("C", IntermediateFieldType.Bool), }; var symbolDef = new IntermediateSymbolDefinition("CustomDef", fieldDefs, null); symbolDef.AddTag("customDef"); var symbol = symbolDef.CreateSymbol(sln, new Identifier(AccessModifier.Public, "customT")); symbol.Set(0, "foo"); symbol.Set(1, 2); symbol.Set(2, true); symbol.AddTag("symbol1tag"); var section = new IntermediateSection("test", SectionType.Product, 65001); section.Symbols.Add(symbol); var intermediate1 = new Intermediate("TestIntermediate", new[] { section }, null); // Intermediate #2 var fieldDefs2 = new[] { new IntermediateFieldDefinition("A", IntermediateFieldType.String), new IntermediateFieldDefinition("B", IntermediateFieldType.Number), new IntermediateFieldDefinition("C", IntermediateFieldType.Bool), new IntermediateFieldDefinition("D", IntermediateFieldType.String), }; var symbolDef2 = new IntermediateSymbolDefinition("CustomDef2", 1, fieldDefs2, null); symbolDef2.AddTag("customDef2"); symbolDef2.AddTag("customDef2 tag2"); var symbol2 = symbolDef2.CreateSymbol(sln, new Identifier(AccessModifier.Public, "customT2")); symbol2.Set(0, "bar"); symbol2.Set(1, 3); symbol2.Set(2, false); symbol2.Set(3, "baz"); symbol2.AddTag("symbol2tag1"); symbol2.AddTag("symbol2tag2"); var section2 = new IntermediateSection("test2", SectionType.Fragment, 65001); section2.Symbols.Add(symbol2); var intermediate2 = new Intermediate("TestIntermediate2", new[] { section2 }, null); // Save var path1 = Path.GetTempFileName(); var path2 = Path.GetTempFileName(); try { intermediate1.Save(path1); intermediate2.Save(path2); var loaded = Intermediate.Load(new[] { path1, path2 }); var loaded1 = loaded.First(); var loaded2 = loaded.Skip(1).Single(); var loadedSymbol1 = loaded1.Sections.Single().Symbols.Single(); var loadedSymbol2 = loaded2.Sections.Single().Symbols.Single(); Assert.True(loadedSymbol1.Definition.HasTag("customDef")); Assert.Equal("foo", loadedSymbol1.AsString(0)); Assert.Equal(2, loadedSymbol1[1].AsNumber()); Assert.True(loadedSymbol1[2].AsBool()); Assert.True(loadedSymbol1.HasTag("symbol1tag")); Assert.True(loadedSymbol2.Definition.HasTag("customDef2")); Assert.True(loadedSymbol2.Definition.HasTag("customDef2 tag2")); Assert.Equal("bar", loadedSymbol2.AsString(0)); Assert.Equal(3, loadedSymbol2[1].AsNumber()); Assert.False(loadedSymbol2[2].AsBool()); Assert.Equal("baz", loadedSymbol2.AsString(3)); Assert.True(loadedSymbol2.HasTag("symbol2tag1")); Assert.True(loadedSymbol2.HasTag("symbol2tag2")); } finally { File.Delete(path2); File.Delete(path1); } }
/// <summary> /// Load sections from the input files. /// </summary> /// <returns>Returns a section collection.</returns> private Dictionary <Section, string> LoadSections() { // 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); foreach (Section section in intermediate.Sections) { sectionFiles[section] = inputFile; } continue; // next file } catch (WixNotIntermediateException) { // try another format } // try loading as a library file try { Library library = Library.Load(inputFileFullPath, linker.TableDefinitions, false, false); foreach (Section section in library.Sections) { sectionFiles[section] = inputFile; } continue; // next file } catch (WixNotLibraryException) { this.OnMessage(LuxBuildErrors.CouldntLoadInput(inputFile)); } } } } return(sectionFiles); }
public Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) { return(Intermediate.Load(typeof(ExampleExtensionData).Assembly, "Example.Extension.Example.wixlib", symbolDefinitions)); }
public override Intermediate GetLibrary(ITupleDefinitionCreator tupleDefinitions) { return(Intermediate.Load(typeof(VSExtensionData).Assembly, "WixToolset.VisualStudio.vs.wixlib", tupleDefinitions)); }
public Intermediate GetLibrary(ITupleDefinitionCreator tupleDefinitions) { return(Intermediate.Load(typeof(ExampleExtensionData).Assembly, "Example.Extension.Data.Example.wir", tupleDefinitions)); }
/// <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); }
public void CanBuildSimpleBundle() { var folder = TestData.Get(@"TestData\SimpleBundle"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var exePath = Path.Combine(baseFolder, @"bin\test.exe"); var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb"); var baFolderPath = Path.Combine(baseFolder, "ba"); var extractFolderPath = Path.Combine(baseFolder, "extract"); var result = WixRunner.Execute(new[] { "build", Path.Combine(folder, "Bundle.wxs"), "-loc", Path.Combine(folder, "Bundle.en-us.wxl"), "-bindpath", Path.Combine(folder, "data"), "-intermediateFolder", intermediateFolder, "-o", exePath, }); result.AssertSuccess(); Assert.Empty(result.Messages.Where(m => m.Level == MessageLevel.Warning)); Assert.True(File.Exists(exePath)); Assert.True(File.Exists(pdbPath)); using (var wixOutput = WixOutput.Read(pdbPath)) { var intermediate = Intermediate.Load(wixOutput); var section = intermediate.Sections.Single(); var bundleSymbol = section.Symbols.OfType <WixBundleSymbol>().Single(); Assert.Equal("1.0.0.0", bundleSymbol.Version); var previousVersion = bundleSymbol.Fields[(int)WixBundleSymbolFields.Version].PreviousValue; Assert.Equal("!(bind.packageVersion.test.msi)", previousVersion.AsString()); var msiSymbol = section.Symbols.OfType <WixBundlePackageSymbol>().Single(); Assert.Equal("test.msi", msiSymbol.Id.Id); var extractResult = BundleExtractor.ExtractBAContainer(null, exePath, baFolderPath, extractFolderPath); extractResult.AssertSuccess(); var burnManifestData = wixOutput.GetData(BurnConstants.BurnManifestWixOutputStreamName); var extractedBurnManifestData = File.ReadAllText(Path.Combine(baFolderPath, "manifest.xml"), Encoding.UTF8); Assert.Equal(extractedBurnManifestData, burnManifestData); var baManifestData = wixOutput.GetData(BurnConstants.BootstrapperApplicationDataWixOutputStreamName); var extractedBaManifestData = File.ReadAllText(Path.Combine(baFolderPath, "BootstrapperApplicationData.xml"), Encoding.UTF8); Assert.Equal(extractedBaManifestData, baManifestData); var bextManifestData = wixOutput.GetData(BurnConstants.BundleExtensionDataWixOutputStreamName); var extractedBextManifestData = File.ReadAllText(Path.Combine(baFolderPath, "BundleExtensionData.xml"), Encoding.UTF8); Assert.Equal(extractedBextManifestData, bextManifestData); var logElements = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Log"); var logElement = (XmlNode)Assert.Single(logElements); Assert.Equal("<Log PathVariable='WixBundleLog' Prefix='~TestBundle' Extension='log' />", logElement.GetTestXml()); var registrationElements = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Registration"); var registrationElement = (XmlNode)Assert.Single(registrationElements); Assert.Equal($"<Registration Id='{bundleSymbol.BundleId}' ExecutableName='test.exe' PerMachine='yes' Tag='' Version='1.0.0.0' ProviderKey='{bundleSymbol.BundleId}'>" + "<Arp Register='yes' DisplayName='~TestBundle' DisplayVersion='1.0.0.0' Publisher='Example Corporation' />" + "</Registration>", registrationElement.GetTestXml()); } } }
public void CanBuildHeatFileWithMultipleFilesPackage(BuildSystem buildSystem) { var sourceFolder = TestData.Get(@"TestData\HeatFileMultipleFilesSameFileName"); using (var fs = new TestDataFolderFileSystem()) { fs.Initialize(sourceFolder); var baseFolder = fs.BaseFolder; var binFolder = Path.Combine(baseFolder, @"bin\"); var intermediateFolder = Path.Combine(baseFolder, @"obj\"); var projectPath = Path.Combine(baseFolder, "HeatFileMultipleFilesSameFileName.wixproj"); var result = MsbuildUtilities.BuildProject(buildSystem, projectPath); result.AssertSuccess(); var heatCommandLines = MsbuildUtilities.GetToolCommandLines(result, "heat", "file", buildSystem, true); Assert.Equal(2, heatCommandLines.Count()); var warnings = result.Output.Where(line => line.Contains(": warning")); Assert.Empty(warnings); var generatedFilePath = Path.Combine(intermediateFolder, "x86", "Release", "_TxtProductComponents_INSTALLFOLDER_MyProgram.txt_file.wxs"); Assert.True(File.Exists(generatedFilePath)); var generatedContents = File.ReadAllText(generatedFilePath); var testXml = generatedContents.GetTestXml(); Assert.Equal("<Wix>" + "<Fragment>" + "<DirectoryRef Id='INSTALLFOLDER'>" + "<Component Id='MyProgram.txt' Guid='*'>" + @"<File Id='MyProgram.txt' KeyPath='yes' Source='SourceDir\MyProgram.txt' />" + "</Component>" + "</DirectoryRef>" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='TxtProductComponents'>" + "<ComponentRef Id='MyProgram.txt' />" + "</ComponentGroup>" + "</Fragment>" + "</Wix>", testXml); generatedFilePath = Path.Combine(intermediateFolder, "x86", "Release", "_JsonProductComponents_INSTALLFOLDER_MyProgram.json_file.wxs"); Assert.True(File.Exists(generatedFilePath)); generatedContents = File.ReadAllText(generatedFilePath); testXml = generatedContents.GetTestXml(); Assert.Equal("<Wix>" + "<Fragment>" + "<DirectoryRef Id='INSTALLFOLDER'>" + "<Component Id='MyProgram.json' Guid='*'>" + @"<File Id='MyProgram.json' KeyPath='yes' Source='SourceDir\MyProgram.json' />" + "</Component>" + "</DirectoryRef>" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='JsonProductComponents'>" + "<ComponentRef Id='MyProgram.json' />" + "</ComponentGroup>" + "</Fragment>" + "</Wix>", testXml); var pdbPath = Path.Combine(binFolder, "x86", "Release", "HeatFileMultipleFilesSameFileName.wixpdb"); Assert.True(File.Exists(pdbPath)); var intermediate = Intermediate.Load(pdbPath); var section = intermediate.Sections.Single(); var fileSymbols = section.Symbols.OfType <FileSymbol>().ToArray(); Assert.Equal(@"SourceDir\MyProgram.txt", fileSymbols[0][FileSymbolFields.Source].PreviousValue.AsPath().Path); Assert.Equal(@"SourceDir\MyProgram.json", fileSymbols[1][FileSymbolFields.Source].PreviousValue.AsPath().Path); } }
public void CanBuildWithExtensionUsingMultipleWixlibs() { var folder = TestData.Get(@"TestData\ComplexExampleExtension"); var extensionPath = Path.GetFullPath(new Uri(typeof(ExampleExtensionFactory).Assembly.CodeBase).LocalPath); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var result = WixRunner.Execute(new[] { "build", Path.Combine(folder, "PackageComponents.wxs"), "-ext", extensionPath, "-intermediateFolder", intermediateFolder, "-o", Path.Combine(intermediateFolder, @"components.wixlib") }); result.AssertSuccess(); result = WixRunner.Execute(new[] { "build", Path.Combine(folder, "OtherComponents.wxs"), "-ext", extensionPath, "-intermediateFolder", intermediateFolder, "-o", Path.Combine(intermediateFolder, @"other.wixlib") }); result.AssertSuccess(); result = WixRunner.Execute(new[] { "build", Path.Combine(folder, "Package.wxs"), "-loc", Path.Combine(folder, "Package.en-us.wxl"), "-lib", Path.Combine(intermediateFolder, @"components.wixlib"), "-lib", Path.Combine(intermediateFolder, @"other.wixlib"), "-ext", extensionPath, "-bindpath", Path.Combine(folder, "data"), "-intermediateFolder", intermediateFolder, "-o", Path.Combine(intermediateFolder, @"bin\test.msi") }); result.AssertSuccess(); var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"bin\test.wixpdb")); var section = intermediate.Sections.Single(); var fileSymbols = section.Symbols.OfType <FileSymbol>().OrderBy(t => Path.GetFileName(t.Source.Path)).ToArray(); Assert.Equal(Path.Combine(folder, @"data\example.txt"), fileSymbols[0][FileSymbolFields.Source].AsPath().Path); Assert.Equal(@"example.txt", fileSymbols[0][FileSymbolFields.Source].PreviousValue.AsPath().Path); Assert.Equal(Path.Combine(folder, @"data\other.txt"), fileSymbols[1][FileSymbolFields.Source].AsPath().Path); Assert.Equal(@"other.txt", fileSymbols[1][FileSymbolFields.Source].PreviousValue.AsPath().Path); var examples = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).ToArray(); Assert.Equal(new string[] { "Foo", "Other" }, examples.Select(t => t.Id?.Id).ToArray()); Assert.Equal(new[] { "Bar", "Value" }, examples.Select(t => t[0].AsString()).ToArray()); } }
public void CanBuildHeatProjectSdkStyle(BuildSystem buildSystem, bool useToolsVersion) { var sourceFolder = TestData.Get(@"TestData\HeatProject"); using (var fs = new TestDataFolderFileSystem()) { fs.Initialize(sourceFolder); var baseFolder = Path.Combine(fs.BaseFolder, "HeatProjectSdkStyle"); var binFolder = Path.Combine(baseFolder, @"bin\"); var intermediateFolder = Path.Combine(baseFolder, @"obj\"); var projectPath = Path.Combine(baseFolder, "HeatProjectSdkStyle.wixproj"); var referencedProjectPath = Path.Combine(fs.BaseFolder, "SdkStyleCs", "SdkStyleCs.csproj"); var result = MsbuildUtilities.BuildProject(buildSystem, referencedProjectPath, new[] { "-t:restore", }); result.AssertSuccess(); result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] { useToolsVersion ? $"-p:HarvestProjectsUseToolsVersion=true" : String.Empty, }); result.AssertSuccess(); var heatCommandLines = MsbuildUtilities.GetToolCommandLines(result, "heat", "project", buildSystem, true); var heatCommandLine = Assert.Single(heatCommandLines); if (useToolsVersion && buildSystem != BuildSystem.DotNetCoreSdk) { Assert.Contains("-usetoolsversion", heatCommandLine); } else { Assert.DoesNotContain("-usetoolsversion", heatCommandLine); } var warnings = result.Output.Where(line => line.Contains(": warning")); Assert.Empty(warnings); var generatedFilePath = Path.Combine(intermediateFolder, "x86", "Release", "_SdkStyleCs.wxs"); Assert.True(File.Exists(generatedFilePath)); var generatedContents = File.ReadAllText(generatedFilePath); var testXml = generatedContents.GetTestXml(); Assert.Equal(@"<Wix>" + "<Fragment>" + "<DirectoryRef Id='SdkStyleCs.Binaries'>" + "<Component Id='SdkStyleCs.Binaries.SdkStyleCs.dll' Guid='*'>" + "<File Id='SdkStyleCs.Binaries.SdkStyleCs.dll' Source='$(var.SdkStyleCs.TargetDir)\\SdkStyleCs.dll' />" + "</Component>" + "</DirectoryRef>" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='SdkStyleCs.Binaries'>" + "<ComponentRef Id='SdkStyleCs.Binaries.SdkStyleCs.dll' />" + "</ComponentGroup>" + "</Fragment>" + "<Fragment>" + "<DirectoryRef Id='SdkStyleCs.Symbols'>" + "<Component Id='SdkStyleCs.Symbols.SdkStyleCs.pdb' Guid='*'>" + "<File Id='SdkStyleCs.Symbols.SdkStyleCs.pdb' Source='$(var.SdkStyleCs.TargetDir)\\SdkStyleCs.pdb' />" + "</Component>" + "</DirectoryRef>" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='SdkStyleCs.Symbols'>" + "<ComponentRef Id='SdkStyleCs.Symbols.SdkStyleCs.pdb' />" + "</ComponentGroup>" + "</Fragment>" + "<Fragment>" + "<DirectoryRef Id='SdkStyleCs.Sources'>" + "<Component Id='SdkStyleCs.Sources.SdkStyleCs.cs' Guid='*'>" + "<File Id='SdkStyleCs.Sources.SdkStyleCs.cs' Source='$(var.SdkStyleCs.ProjectDir)\\SdkStyleCs.cs' />" + "</Component>" + "<Component Id='SdkStyleCs.Sources.SdkStyleCs.csproj' Guid='*'>" + "<File Id='SdkStyleCs.Sources.SdkStyleCs.csproj' Source='$(var.SdkStyleCs.ProjectDir)\\SdkStyleCs.csproj' />" + "</Component>" + "</DirectoryRef>" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='SdkStyleCs.Sources'>" + "<ComponentRef Id='SdkStyleCs.Sources.SdkStyleCs.cs' />" + "<ComponentRef Id='SdkStyleCs.Sources.SdkStyleCs.csproj' />" + "</ComponentGroup>" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='SdkStyleCs.Content' />" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='SdkStyleCs.Satellites' />" + "</Fragment>" + "<Fragment>" + "<ComponentGroup Id='SdkStyleCs.Documents' />" + "</Fragment>" + "</Wix>", testXml); var pdbPath = Path.Combine(binFolder, "x86", "Release", "HeatProjectSdkStyle.wixpdb"); Assert.True(File.Exists(pdbPath)); var intermediate = Intermediate.Load(pdbPath); var section = intermediate.Sections.Single(); var fileSymbol = section.Symbols.OfType <FileSymbol>().Single(); Assert.Equal(Path.Combine(fs.BaseFolder, "SdkStyleCs", "bin", "Release", "netstandard2.0\\\\SdkStyleCs.dll"), fileSymbol[FileSymbolFields.Source].PreviousValue.AsPath().Path); } }
/// <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(); if (null != this.extensionList) { ExtensionManager extensionManager = new ExtensionManager(); foreach (string extension in this.extensionList) { extensionManager.Load(extension); } foreach (IExtensionData data in extensionManager.Create <IExtensionData>()) { linker.AddExtensionData(data); } } // 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)) { FileFormat format = FileStructure.GuessFileFormatFromExtension(Path.GetExtension(inputFileFullPath)); bool retry; do { retry = false; try { switch (format) { case FileFormat.Wixobj: Intermediate intermediate = Intermediate.Load(inputFile, linker.TableDefinitions, false); Generator.LoadSections(inputFile, sectionFiles, intermediate.Sections); break; default: Library library = Library.Load(inputFile, linker.TableDefinitions, false); Generator.LoadSections(inputFile, sectionFiles, library.Sections); break; } } catch (WixUnexpectedFileFormatException e) { format = e.FileFormat; retry = (FileFormat.Wixobj != format && FileFormat.Wixlib != format); // .wixobj and .wixout are supported by lux. if (!retry) { this.OnMessage(LuxBuildErrors.CouldntLoadInput(inputFile)); } } } while (retry); } } } return(sectionFiles); }
/// <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 { XmlSchemaCollection objectSchema = new XmlSchemaCollection(); FileInfo currentFile = null; ArrayList intermediates = new ArrayList(); Librarian librarian = null; // 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.FoundError) { return(this.messageHandler.PostProcess()); } if (0 == this.objectFiles.Count) { this.showHelp = true; } else if (null == this.outputFile) { if (1 < this.objectFiles.Count) { throw new ArgumentException("must specify output file when using more than one input file", "-out"); } FileInfo fi = (FileInfo)this.objectFiles[0]; this.outputFile = new FileInfo(Path.ChangeExtension(fi.Name, ".wix")); // we'll let the linker change the extension later } 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 outputFile] 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(" -ext extension (class, assembly), should extend SchemaExtension or BinderExtension"); Console.WriteLine(" -ss suppress schema validation of documents (performance boost)"); Console.WriteLine(" -sv suppress intermediate file version mismatch checking"); Console.WriteLine(" -ust use small table definitions (for backwards compatiblity)"); Console.WriteLine(" -wx treat warnings as errors"); Console.WriteLine(" -w<N> set the warning level (0: show all, 3: show none)"); Console.WriteLine(" -sw suppress all warnings (same as -w3)"); Console.WriteLine(" -sw<N> suppress warning with specific message ID"); Console.WriteLine(" -v verbose output (same as -v2)"); Console.WriteLine(" -v<N> sets the level of verbose output (0: most output, 3: none)"); 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(" .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.PostProcess()); } // create the librarian librarian = new Librarian(this.useSmallTables); librarian.Message += new MessageEventHandler(this.messageHandler.Display); // load any extensions foreach (string extension in this.extensionList) { Type extensionType = Type.GetType(extension); if (null == extensionType) { throw new WixInvalidExtensionException(extension); } if (extensionType.IsSubclassOf(typeof(SchemaExtension))) { librarian.AddExtension((SchemaExtension)Activator.CreateInstance(extensionType)); } } // load the object schema if (!this.suppressSchema) { Assembly wixAssembly = Assembly.Load("wix"); using (Stream objectsSchemaStream = wixAssembly.GetManifestResourceStream("Microsoft.Tools.WindowsInstallerXml.Xsd.objects.xsd")) { XmlReader reader = new XmlTextReader(objectsSchemaStream); objectSchema.Add("http://schemas.microsoft.com/wix/2003/04/objects", reader); } } // add the Intermediates to the librarian foreach (FileInfo objectFile in this.objectFiles) { currentFile = objectFile; // load the object file into an intermediate object and add it to the list to be linked using (Stream fileStream = new FileStream(currentFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { XmlReader fileReader = new XmlTextReader(fileStream); try { XmlReader intermediateReader = fileReader; if (!this.suppressSchema) { intermediateReader = new XmlValidatingReader(fileReader); ((XmlValidatingReader)intermediateReader).Schemas.Add(objectSchema); } Intermediate intermediate = Intermediate.Load(intermediateReader, currentFile.FullName, librarian.TableDefinitions, this.suppressVersionCheck); intermediates.Add(intermediate); continue; // next file } catch (WixNotIntermediateException) { // try another format } Library objLibrary = Library.Load(currentFile.FullName, librarian.TableDefinitions, this.suppressVersionCheck); intermediates.AddRange(objLibrary.Intermediates); } currentFile = null; } // and now for the fun part Library library = librarian.Combine((Intermediate[])intermediates.ToArray(typeof(Intermediate))); // save the library output if an error did not occur if (null != library) { library.Save(this.outputFile.FullName); } } catch (WixException we) { // TODO: once all WixExceptions are converted to errors, this clause // should be a no-op that just catches WixFatalErrorException's this.messageHandler.Display("lit.exe", "LIT", we); return(1); } catch (Exception e) { this.OnMessage(WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } return(this.messageHandler.PostProcess()); }
public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) { return(Intermediate.Load(typeof(BalExtensionData).Assembly, "WixToolset.Bal.bal.wixlib", symbolDefinitions)); }
/// <summary> /// Create the library. /// </summary> private void Run() { // Create the librarian and add the extension data. Librarian librarian = new Librarian(); foreach (IExtensionData data in this.extensionData) { librarian.AddExtensionData(data); } // Add the sections to the librarian List <Section> sections = new List <Section>(); foreach (string file in this.commandLine.Files) { string inputFile = Path.GetFullPath(file); FileFormat format = FileStructure.GuessFileFormatFromExtension(Path.GetExtension(inputFile)); bool retry; do { retry = false; try { switch (format) { case FileFormat.Wixobj: Intermediate intermediate = Intermediate.Load(inputFile, librarian.TableDefinitions, this.commandLine.SuppressVersionCheck); sections.AddRange(intermediate.Sections); break; default: Library loadedLibrary = Library.Load(inputFile, librarian.TableDefinitions, this.commandLine.SuppressVersionCheck); sections.AddRange(loadedLibrary.Sections); break; } } catch (WixUnexpectedFileFormatException e) { format = e.FileFormat; retry = (FileFormat.Wixobj == format || FileFormat.Wixlib == format); // .wixobj and .wixout are supported by lit. if (!retry) { Messaging.Instance.OnMessage(e.Error); } } } while (retry); } // Stop processing if any errors were found loading object files. if (Messaging.Instance.EncounteredError) { return; } // and now for the fun part Library library = librarian.Combine(sections); // Add any localization files and save the library output if an error did not occur if (null != library) { foreach (string localizationFile in this.commandLine.LocalizationFiles) { Localization localization = Localizer.ParseLocalizationFile(localizationFile, librarian.TableDefinitions); if (null != localization) { library.AddLocalization(localization); } } // If there was an error adding localization files, then bail. if (Messaging.Instance.EncounteredError) { return; } LibraryBinaryFileResolver resolver = null; if (this.commandLine.BindFiles) { resolver = new LibraryBinaryFileResolver(); resolver.FileManagers = this.fileManagers; resolver.VariableResolver = new WixVariableResolver(); BinderFileManagerCore core = new BinderFileManagerCore(); core.AddBindPaths(this.commandLine.BindPaths, BindStage.Normal); foreach (IBinderFileManager fileManager in resolver.FileManagers) { fileManager.Core = core; } } library.Save(this.commandLine.OutputFile, resolver); } }
/// <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); }
public void CanBuildSimpleBundle() { var folder = TestData.Get(@"TestData\SimpleBundle"); using (var fs = new DisposableFileSystem()) { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var exePath = Path.Combine(baseFolder, @"bin\test.exe"); var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb"); var baFolderPath = Path.Combine(baseFolder, "ba"); var extractFolderPath = Path.Combine(baseFolder, "extract"); var result = WixRunner.Execute(new[] { "build", Path.Combine(folder, "Bundle.wxs"), "-loc", Path.Combine(folder, "Bundle.en-us.wxl"), "-bindpath", Path.Combine(folder, "data"), "-intermediateFolder", intermediateFolder, "-o", exePath, }); result.AssertSuccess(); Assert.Empty(result.Messages.Where(m => m.Level == MessageLevel.Warning)); Assert.True(File.Exists(exePath)); Assert.True(File.Exists(pdbPath)); using (var wixOutput = WixOutput.Read(pdbPath)) { var intermediate = Intermediate.Load(wixOutput); var section = intermediate.Sections.Single(); var bundleSymbol = section.Symbols.OfType <WixBundleSymbol>().Single(); Assert.Equal("1.0.0.0", bundleSymbol.Version); var previousVersion = bundleSymbol.Fields[(int)WixBundleSymbolFields.Version].PreviousValue; Assert.Equal("!(bind.packageVersion.test.msi)", previousVersion.AsString()); var msiSymbol = section.Symbols.OfType <WixBundlePackageSymbol>().Single(); Assert.Equal("test.msi", msiSymbol.Id.Id); var extractResult = BundleExtractor.ExtractBAContainer(null, exePath, baFolderPath, extractFolderPath); extractResult.AssertSuccess(); var burnManifestData = wixOutput.GetData(BurnConstants.BurnManifestWixOutputStreamName); var extractedBurnManifestData = File.ReadAllText(Path.Combine(baFolderPath, "manifest.xml"), Encoding.UTF8); Assert.Equal(extractedBurnManifestData, burnManifestData); var baManifestData = wixOutput.GetData(BurnConstants.BootstrapperApplicationDataWixOutputStreamName); var extractedBaManifestData = File.ReadAllText(Path.Combine(baFolderPath, "BootstrapperApplicationData.xml"), Encoding.UTF8); Assert.Equal(extractedBaManifestData, baManifestData); var bextManifestData = wixOutput.GetData(BurnConstants.BundleExtensionDataWixOutputStreamName); var extractedBextManifestData = File.ReadAllText(Path.Combine(baFolderPath, "BundleExtensionData.xml"), Encoding.UTF8); Assert.Equal(extractedBextManifestData, bextManifestData); var logElements = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Log"); var logElement = (XmlNode)Assert.Single(logElements); Assert.Equal("<Log PathVariable='WixBundleLog' Prefix='~TestBundle' Extension='log' />", logElement.GetTestXml()); var registrationElements = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Registration"); var registrationElement = (XmlNode)Assert.Single(registrationElements); Assert.Equal($"<Registration Id='{bundleSymbol.BundleId}' ExecutableName='test.exe' PerMachine='yes' Tag='' Version='1.0.0.0' ProviderKey='{bundleSymbol.BundleId}'>" + "<Arp Register='yes' DisplayName='~TestBundle' DisplayVersion='1.0.0.0' Publisher='Example Corporation' />" + "</Registration>", registrationElement.GetTestXml()); var msiPayloads = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Payload[@Id='test.msi']"); var msiPayload = (XmlNode)Assert.Single(msiPayloads); Assert.Equal("<Payload Id='test.msi' FilePath='test.msi' FileSize='*' Hash='*' Packaging='embedded' SourcePath='a0' Container='WixAttachedContainer' />", msiPayload.GetTestXml(new Dictionary <string, List <string> >() { { "Payload", new List <string> { "FileSize", "Hash" } } })); } var manifestResource = new Resource(ResourceType.Manifest, "#1", 1033); manifestResource.Load(exePath); var actualManifestData = Encoding.UTF8.GetString(manifestResource.Data); Assert.Equal("<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">" + "<assemblyIdentity name=\"test.exe\" version=\"1.0.0.0\" processorArchitecture=\"x86\" type=\"win32\" />" + "<description>~TestBundle</description>" + "<dependency><dependentAssembly><assemblyIdentity name=\"Microsoft.Windows.Common-Controls\" version=\"6.0.0.0\" processorArchitecture=\"x86\" publicKeyToken=\"6595b64144ccf1df\" language=\"*\" type=\"win32\" /></dependentAssembly></dependency>" + "<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\"><application><supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\" /><supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\" /><supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" /><supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\" /><supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\" /></application></compatibility>" + "<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\"><security><requestedPrivileges><requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\" /></requestedPrivileges></security></trustInfo>" + "<application xmlns=\"urn:schemas-microsoft-com:asm.v3\"><windowsSettings><dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true/pm</dpiAware><dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2, PerMonitor</dpiAwareness></windowsSettings></application>" + "</assembly>", actualManifestData); } }
/// <summary> /// Create the library. /// </summary> private void Run() { // Create the librarian and add the extension data. Librarian librarian = new Librarian(); foreach (IExtensionData data in this.extensionData) { librarian.AddExtensionData(data); } // Add the sections to the librarian SectionCollection sections = new SectionCollection(); foreach (string file in this.commandLine.Files) { string inputFile = Path.GetFullPath(file); // try loading as an object file try { Intermediate intermediate = Intermediate.Load(inputFile, librarian.TableDefinitions, this.commandLine.SuppressVersionCheck, true); sections.AddRange(intermediate.Sections); continue; // next file } catch (WixNotIntermediateException) { // try another format } // try loading as a library file Library loadedLibrary = Library.Load(inputFile, librarian.TableDefinitions, this.commandLine.SuppressVersionCheck, true); 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) { foreach (string localizationFile in this.commandLine.LocalizationFiles) { Localization localization = Localization.Load(localizationFile, librarian.TableDefinitions, true); library.AddLocalization(localization); } LibraryBinaryFileResolver resolver = null; if (this.commandLine.BindFiles) { resolver = new LibraryBinaryFileResolver(); resolver.FileManagers = this.fileManagers; resolver.VariableResolver = new WixVariableResolver(); BinderFileManagerCore core = new BinderFileManagerCore(); core.AddBindPaths(this.commandLine.BindPaths, BindStage.Normal); foreach (IBinderFileManager fm in resolver.FileManagers) { fm.Core = core; } } library.Save(this.commandLine.OutputFile, resolver); } }
private void Run(IMessaging messaging) { #if false // Initialize the variable resolver from the command line. WixVariableResolver wixVariableResolver = new WixVariableResolver(); foreach (var wixVar in this.commandLine.Variables) { wixVariableResolver.AddVariable(wixVar.Key, wixVar.Value); } // Initialize the linker from the command line. Linker linker = new Linker(); linker.UnreferencedSymbolsFile = this.commandLine.UnreferencedSymbolsFile; linker.ShowPedanticMessages = this.commandLine.ShowPedanticMessages; linker.WixVariableResolver = wixVariableResolver; foreach (IExtensionData data in this.extensionData) { linker.AddExtensionData(data); } // Initialize the binder from the command line. WixToolset.Binder binder = new WixToolset.Binder(); binder.CabCachePath = this.commandLine.CabCachePath; binder.ContentsFile = this.commandLine.ContentsFile; binder.BuiltOutputsFile = this.commandLine.BuiltOutputsFile; binder.OutputsFile = this.commandLine.OutputsFile; binder.WixprojectFile = this.commandLine.WixprojectFile; binder.BindPaths.AddRange(this.commandLine.BindPaths); binder.CabbingThreadCount = this.commandLine.CabbingThreadCount; if (this.commandLine.DefaultCompressionLevel.HasValue) { binder.DefaultCompressionLevel = this.commandLine.DefaultCompressionLevel.Value; } binder.Ices.AddRange(this.commandLine.Ices); binder.SuppressIces.AddRange(this.commandLine.SuppressIces); binder.SuppressAclReset = this.commandLine.SuppressAclReset; binder.SuppressLayout = this.commandLine.SuppressLayout; binder.SuppressValidation = this.commandLine.SuppressValidation; binder.PdbFile = this.commandLine.SuppressWixPdb ? null : this.commandLine.PdbFile; binder.TempFilesLocation = AppCommon.GetTempLocation(); binder.WixVariableResolver = wixVariableResolver; foreach (IBinderExtension extension in this.binderExtensions) { binder.AddExtension(extension); } foreach (IBinderFileManager fileManager in this.fileManagers) { binder.AddExtension(fileManager); } // Initialize the localizer. Localizer localizer = this.InitializeLocalization(linker.TableDefinitions); if (messaging.EncounteredError) { return; } wixVariableResolver.Localizer = localizer; linker.Localizer = localizer; binder.Localizer = localizer; // Loop through all the believed object files. List <Section> sections = new List <Section>(); Output output = null; foreach (string inputFile in this.commandLine.Files) { string inputFileFullPath = Path.GetFullPath(inputFile); FileFormat format = FileStructure.GuessFileFormatFromExtension(Path.GetExtension(inputFileFullPath)); bool retry; do { retry = false; try { switch (format) { case FileFormat.Wixobj: Intermediate intermediate = Intermediate.Load(inputFileFullPath, linker.TableDefinitions, this.commandLine.SuppressVersionCheck); sections.AddRange(intermediate.Sections); break; case FileFormat.Wixlib: Library library = Library.Load(inputFileFullPath, linker.TableDefinitions, this.commandLine.SuppressVersionCheck); AddLibraryLocalizationsToLocalizer(library, this.commandLine.Cultures, localizer); sections.AddRange(library.Sections); break; default: output = Output.Load(inputFileFullPath, this.commandLine.SuppressVersionCheck); break; } } catch (WixUnexpectedFileFormatException e) { format = e.FileFormat; retry = (FileFormat.Wixobj == format || FileFormat.Wixlib == format || FileFormat.Wixout == format); // .wixobj, .wixout and .wixout are supported by light. if (!retry) { messaging.OnMessage(e.Error); } } } while (retry); } // Stop processing if any errors were found loading object files. if (messaging.EncounteredError) { return; } // and now for the fun part if (null == output) { OutputType expectedOutputType = OutputType.Unknown; if (!String.IsNullOrEmpty(this.commandLine.OutputFile)) { expectedOutputType = Output.GetOutputType(Path.GetExtension(this.commandLine.OutputFile)); } output = linker.Link(sections, expectedOutputType); // If an error occurred during linking, stop processing. if (null == output) { return; } } else if (0 != sections.Count) { throw new InvalidOperationException(LightStrings.EXP_CannotLinkObjFilesWithOutpuFile); } bool tidy = true; // clean up after ourselves by default. try { // only output the xml if its a patch build or user specfied to only output wixout string outputFile = this.commandLine.OutputFile; string outputExtension = Path.GetExtension(outputFile); if (this.commandLine.OutputXml || OutputType.Patch == output.Type) { if (String.IsNullOrEmpty(outputExtension) || outputExtension.Equals(".wix", StringComparison.Ordinal)) { outputExtension = (OutputType.Patch == output.Type) ? ".wixmsp" : ".wixout"; outputFile = Path.ChangeExtension(outputFile, outputExtension); } output.Save(outputFile); } else // finish creating the MSI/MSM { if (String.IsNullOrEmpty(outputExtension) || outputExtension.Equals(".wix", StringComparison.Ordinal)) { outputExtension = Output.GetExtension(output.Type); outputFile = Path.ChangeExtension(outputFile, outputExtension); } binder.Bind(output, outputFile); } } catch (WixException we) // keep files around for debugging IDT issues. { if (we is WixInvalidIdtException) { tidy = false; } throw; } catch (Exception) // keep files around for debugging unexpected exceptions. { tidy = false; throw; } finally { if (null != binder) { binder.Cleanup(tidy); } } return; #endif }
/// <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); }
private Intermediate LoadWixout(IMessaging messaging) { var path = this.commandLine.Files.Single(); return(Intermediate.Load(path)); }
public override Intermediate GetLibrary(ITupleDefinitionCreator tupleDefinitions) { return(Intermediate.Load(typeof(SqlExtensionData).Assembly, "WixToolset.Sql.sql.wixlib", tupleDefinitions)); }
public void CanLoadWixoutAndConvertToIntermediate() { var rootFolder = TestData.Get(); var dataFolder = TestData.Get(@"TestData\Integration"); using (var fs = new DisposableFileSystem()) { var intermediateFolder = fs.GetFolder(); var path = Path.Combine(dataFolder, "test.wixout"); var intermediate = ConvertSymbols.ConvertFile(path); Assert.NotNull(intermediate); Assert.Single(intermediate.Sections); Assert.Equal(String.Empty, intermediate.Id); // Save and load to guarantee round-tripping support. // var wixiplFile = Path.Combine(intermediateFolder, "test.wixipl"); intermediate.Save(wixiplFile); intermediate = Intermediate.Load(wixiplFile); var output = Wix3.Output.Load(path, suppressVersionCheck: true, suppressSchema: true); var wixMediaByDiskId = IndexWixMediaTableByDiskId(output); // Dump to text for easy diffing, with some massaging to keep v3 and v4 diffable. // var tables = output.Tables.Cast <Wix3.Table>(); var wix3Dump = tables .SelectMany(table => table.Rows.Cast <Wix3.Row>() .SelectMany(row => RowToStrings(row, wixMediaByDiskId))) .Where(s => !String.IsNullOrEmpty(s)) .OrderBy(s => s) .ToArray(); var symbols = intermediate.Sections.SelectMany(s => s.Symbols); var assemblySymbolsByFileId = symbols.OfType <AssemblySymbol>().ToDictionary(a => a.Id.Id); var wix4Dump = symbols .SelectMany(symbol => SymbolToStrings(symbol, assemblySymbolsByFileId)) .OrderBy(s => s) .ToArray(); #if false Assert.Equal(wix3Dump, wix4Dump); #else // useful when you want to diff the outputs with another diff tool. var wix3TextDump = String.Join(Environment.NewLine, wix3Dump); var wix4TextDump = String.Join(Environment.NewLine, wix4Dump); var path3 = Path.Combine(Path.GetTempPath(), "~3.txt"); var path4 = Path.Combine(Path.GetTempPath(), "~4.txt"); File.WriteAllText(path3, wix3TextDump); File.WriteAllText(path4, wix4TextDump); Assert.Equal(wix3TextDump, wix4TextDump); #endif } }