/// <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.FoundError) { return(this.messageHandler.PostProcess()); } if (null == this.inputFile) { 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 [-?] [-x basePath] msiFileName xmlFileName"); Console.WriteLine(); Console.WriteLine(" --Convert a Windows Installer database to an XML installation manifest --"); Console.WriteLine(" 1st argument is path to the MSI database to query"); Console.WriteLine(" 2nd argument is path to the XML manifest to create"); Console.WriteLine(); Console.WriteLine(" case-insensitive option arguments may be specified in any order:"); Console.WriteLine(" /s or -s exclude standard sequence actions, process Custom and dialogs"); Console.WriteLine(" /p or -p exclude Package element generation from summary information"); Console.WriteLine(" /n or -n no UI elements processed"); Console.WriteLine(" /ui or -ui only UI elements processed"); Console.WriteLine(" /ext extension (class, assembly), should extend CompilerExtension"); Console.WriteLine(" /x <path> or -x <path> export binary streams from Binary and Icon tables to path"); Console.WriteLine(" /m or -m merge module"); Console.WriteLine(" /notidy or -notidy Do not delete temporary files (for checking results)"); Console.WriteLine(" /e or -e include empty tables"); Console.WriteLine(" /f or -f generate many fragment files via internal heuristic"); Console.WriteLine(" /g or -g generate single monolithic fragment"); Console.WriteLine(" /wx or -wx treat warnings as errors"); Console.WriteLine(" /w<N> or -w<N> set the warning level (0: show all, 3: show none)"); Console.WriteLine(" /sw or -sw suppress all warnings (same as -w3)"); Console.WriteLine(" /sw<N> or -sw<N> suppress warning with specific message ID"); Console.WriteLine(" /v or -v verbose output (same as -v2)"); Console.WriteLine(" /v<N> or -v<N> sets the level of verbose output (0: most output, 3: none)"); Console.WriteLine(" /vsi or -vsi filter out problematic Visual Studio Installer constructs"); Console.WriteLine(" /is or -is filter out problematic InstallShield constructs"); Console.WriteLine(" /nologo or -nologo skip printing dark logo information"); Console.WriteLine(" /z or -z write explicit sequence numbers (no relative references)"); Console.WriteLine(" /? or -? show this help info, same as if no arguments supplied"); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(" CONVERTING FROM MSI to WiX"); Console.WriteLine(); Console.WriteLine(" In general, WiX does a good job of validating your Xml source code."); Console.WriteLine(" Therefore, you will encounter logical errors -- invalid attributes, for"); Console.WriteLine(" example -- that were ignored by MSI but will need to be fixed for WiX. "); Console.WriteLine(); return(this.messageHandler.PostProcess()); } // print friendly message saying what file is being compiled Console.WriteLine(this.inputFile); // create the decompiler Decompiler decompiler = new Decompiler(); // 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(DecompilerExtension))) { DecompilerExtension decompilerExtensionObject = Activator.CreateInstance(extensionType) as DecompilerExtension; decompiler.AddExtension(decompilerExtensionObject); } if (!extensionType.IsSubclassOf(typeof(DecompilerExtension))) { throw new WixInvalidExtensionException(extension); } } // Set the Properties decompiler.SkipUI = this.skipUI; decompiler.SkipVSI = this.skipVSI; decompiler.SkipInstallShield = this.skipInstallShield; decompiler.ProcessUIOnly = this.processUIOnly; decompiler.SkipSequenceTables = this.skipSequenceTables; decompiler.ExplicitSequenceTables = this.explicitSequenceTables; decompiler.SkipSummaryInfo = this.skipSummaryInfo; decompiler.ExportBinaries = this.exportBinaries; decompiler.IsMergeModule = this.processingModule; decompiler.IsFragmentContainer = this.processingFragment; decompiler.GenerateFragments = this.generateFragments; decompiler.KeepEmptyTables = this.keepEmptyTables; decompiler.AddComments = this.addComments; decompiler.ExportBasePath = this.basePath; decompiler.Tidy = this.tidy; decompiler.Message += new MessageEventHandler(this.messageHandler.Display); // and now we do what we came here to do... decompiler.Decompile(this.inputFile, this.outputFile); } 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("dark.exe", "DARK", 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()); }
/// <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> public 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.FoundError) { return this.messageHandler.PostProcess(); } if (null == this.inputFile) { 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 [-?] [-x basePath] msiFileName xmlFileName"); Console.WriteLine(); Console.WriteLine(" --Convert a Windows Installer database to an XML installation manifest --"); Console.WriteLine(" 1st argument is path to the MSI database to query"); Console.WriteLine(" 2nd argument is path to the XML manifest to create"); Console.WriteLine(); Console.WriteLine(" case-insensitive option arguments may be specified in any order:"); Console.WriteLine(" /s or -s exclude standard sequence actions, process Custom and dialogs"); Console.WriteLine(" /p or -p exclude Package element generation from summary information"); Console.WriteLine(" /n or -n no UI elements processed"); Console.WriteLine(" /ui or -ui only UI elements processed"); Console.WriteLine(" /ext extension (class, assembly), should extend CompilerExtension"); Console.WriteLine(" /x <path> or -x <path> export binary streams from Binary and Icon tables to path"); Console.WriteLine(" /m or -m merge module"); Console.WriteLine(" /notidy or -notidy Do not delete temporary files (for checking results)"); Console.WriteLine(" /e or -e include empty tables"); Console.WriteLine(" /f or -f generate many fragment files via internal heuristic"); Console.WriteLine(" /g or -g generate single monolithic fragment"); Console.WriteLine(" /wx or -wx treat warnings as errors"); Console.WriteLine(" /w<N> or -w<N> set the warning level (0: show all, 3: show none)"); Console.WriteLine(" /sw or -sw suppress all warnings (same as -w3)"); Console.WriteLine(" /sw<N> or -sw<N> suppress warning with specific message ID"); Console.WriteLine(" /v or -v verbose output (same as -v2)"); Console.WriteLine(" /v<N> or -v<N> sets the level of verbose output (0: most output, 3: none)"); Console.WriteLine(" /vsi or -vsi filter out problematic Visual Studio Installer constructs"); Console.WriteLine(" /is or -is filter out problematic InstallShield constructs"); Console.WriteLine(" /nologo or -nologo skip printing dark logo information"); Console.WriteLine(" /z or -z write explicit sequence numbers (no relative references)"); Console.WriteLine(" /? or -? show this help info, same as if no arguments supplied"); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(" CONVERTING FROM MSI to WiX"); Console.WriteLine(); Console.WriteLine(" In general, WiX does a good job of validating your Xml source code."); Console.WriteLine(" Therefore, you will encounter logical errors -- invalid attributes, for"); Console.WriteLine(" example -- that were ignored by MSI but will need to be fixed for WiX. "); Console.WriteLine(); return this.messageHandler.PostProcess(); } // print friendly message saying what file is being compiled Console.WriteLine(this.inputFile); // create the decompiler Decompiler decompiler = new Decompiler(); // 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(DecompilerExtension))) { DecompilerExtension decompilerExtensionObject = Activator.CreateInstance(extensionType) as DecompilerExtension; decompiler.AddExtension(decompilerExtensionObject); } if (!extensionType.IsSubclassOf(typeof(DecompilerExtension))) { throw new WixInvalidExtensionException(extension); } } // Set the Properties decompiler.SkipUI = this.skipUI; decompiler.SkipVSI = this.skipVSI; decompiler.SkipInstallShield = this.skipInstallShield; decompiler.ProcessUIOnly = this.processUIOnly; decompiler.SkipSequenceTables = this.skipSequenceTables; decompiler.ExplicitSequenceTables = this.explicitSequenceTables; decompiler.SkipSummaryInfo = this.skipSummaryInfo; decompiler.ExportBinaries = this.exportBinaries; decompiler.IsMergeModule = this.processingModule; decompiler.IsFragmentContainer = this.processingFragment; decompiler.GenerateFragments = this.generateFragments; decompiler.KeepEmptyTables = this.keepEmptyTables; decompiler.AddComments = this.addComments; decompiler.ExportBasePath = this.basePath; decompiler.Tidy = this.tidy; decompiler.Message += new MessageEventHandler(this.messageHandler.Display); // and now we do what we came here to do... decompiler.Decompile(this.inputFile, this.outputFile); } 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("dark.exe", "DARK", 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(); }
/// <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 all extensions ExtensionManager extensionManager = new ExtensionManager(); foreach (string extension in this.extensionList) { extensionManager.Load(extension); } foreach (IDecompilerExtension extension in extensionManager.Create <IDecompilerExtension>()) { decompiler.AddExtension(extension); } foreach (IUnbinderExtension extension in extensionManager.Create <IUnbinderExtension>()) { unbinder.AddExtension(extension); } // set options decompiler.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); unbinder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); unbinder.SuppressDemodularization = true; // 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) { 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) { 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> /// 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); } } } }