Example #1
0
        public Wix.Wix Decompile(Output output)
        {
            if (null == output)
            {
                throw new ArgumentNullException("output");
            }

            this.codepage = output.Codepage;
            this.outputType = output.Type;

            // collect the table definitions from the output
            this.tableDefinitions.Clear();
            foreach (Table table in output.Tables)
            {
                this.tableDefinitions.Add(table.Definition);
            }

            // add any missing standard and wix-specific table definitions
            foreach (TableDefinition tableDefinition in Installer.GetTableDefinitions())
            {
                if (!this.tableDefinitions.Contains(tableDefinition.Name))
                {
                    this.tableDefinitions.Add(tableDefinition);
                }
            }

            // add any missing extension table definitions
            foreach (WixExtension extension in this.extensions)
            {
                if (null != extension.TableDefinitions)
                {
                    foreach (TableDefinition tableDefinition in extension.TableDefinitions)
                    {
                        if (!this.tableDefinitions.Contains(tableDefinition.Name))
                        {
                            this.tableDefinitions.Add(tableDefinition);
                        }
                    }
                }
            }

            // if we don't have the temporary files object yet, get one
            if (null == this.tempFiles)
            {
                this.TempFilesLocation = null;
            }
            Directory.CreateDirectory(this.tempFiles.BasePath); // ensure the base path is there

            bool encounteredError = false;
            Wix.IParentElement rootElement;
            Wix.Wix wixElement = new Wix.Wix();

            switch (this.outputType)
            {
                case OutputType.Module:
                    rootElement = new Wix.Module();
                    break;
                case OutputType.PatchCreation:
                    rootElement = new Wix.PatchCreation();
                    break;
                case OutputType.Product:
                    rootElement = new Wix.Product();
                    break;
                default:
                    throw new InvalidOperationException(WixStrings.EXP_UnknownOutputType);
            }
            wixElement.AddChild((Wix.ISchemaElement)rootElement);

            // try to decompile the database file
            try
            {
                this.core = new DecompilerCore(rootElement, this.Message);
                this.core.ShowPedanticMessages = this.showPedanticMessages;

                // stop processing if an error previously occurred
                if (this.core.EncounteredError)
                {
                    return null;
                }

                // initialize the decompiler and its extensions
                foreach (WixExtension extension in this.extensions)
                {
                    if (null != extension.DecompilerExtension)
                    {
                        extension.DecompilerExtension.Core = this.core;
                        extension.DecompilerExtension.InitializeDecompile(output.Tables);
                    }
                }
                this.InitializeDecompile(output.Tables);

                // stop processing if an error previously occurred
                if (this.core.EncounteredError)
                {
                    return null;
                }

                // decompile the tables
                this.DecompileTables(output);

                // finalize the decompiler and its extensions
                this.FinalizeDecompile(output.Tables);
                foreach (WixExtension extension in this.extensions)
                {
                    if (null != extension.DecompilerExtension)
                    {
                        extension.DecompilerExtension.FinalizeDecompile(output.Tables);
                    }
                }
            }
            finally
            {
                encounteredError = this.core.EncounteredError;

                this.core = null;
                foreach (WixExtension extension in this.extensions)
                {
                    if (null != extension.DecompilerExtension)
                    {
                        extension.DecompilerExtension.Core = null;
                    }
                }
            }

            // return the root element only if decompilation completed successfully
            return (encounteredError ? null : wixElement);
        }
Example #2
0
        /// <summary>
        /// main entry point
        /// </summary>
        /// <param name="inputPath">input path.</param>
        /// <param name="outputPath">output path.</param>
        public void Decompile(string inputPath, string outputPath)
        {
            this.standardActions = Common.GetStandardActions();

            if (null == inputPath)
            {
                throw new ArgumentNullException("inputPath", "Input file must be specified.");
            }

            if (null == outputPath)
            {
                throw new ArgumentNullException("outputPath", "Output path must be specified.");
            }

            if (!File.Exists(inputPath))
            {
                throw new FileNotFoundException("Cannot find file to decompile.", inputPath);
            }

            if (!Path.IsPathRooted(inputPath))
            {
                inputPath = Path.GetFullPath(inputPath);
            }

            if (!Path.IsPathRooted(outputPath))
            {
                outputPath = Path.GetFullPath(outputPath);
            }

            XmlTextWriter writer = null;

            try
            {
                // remember the output folder and open the database
                this.outputFolder = Path.GetDirectoryName(outputPath);
                if (0 == this.outputFolder.Length)
                {
                    this.outputFolder = System.Environment.CurrentDirectory;
                }

                if (null == this.exportBasePath || 0 == this.exportBasePath.Length)
                {
                    this.exportBasePath = this.outputFolder;
                }
                else if (!Path.IsPathRooted(this.exportBasePath))
                {
                    this.exportBasePath = Path.GetFullPath(Path.Combine(this.outputFolder, this.exportBasePath));
                }

                // create a temporary directory
                this.extractFolder = Path.Combine(this.exportBasePath, "extract");
                Directory.CreateDirectory(this.extractFolder);

                this.imageFolder = Path.GetDirectoryName(inputPath);
                if (null == this.imageBasePath || 0 == this.imageBasePath.Length)
                {
                    this.imageBasePath = this.imageFolder;
                }
                else if (!Path.IsPathRooted(this.imageBasePath))
                {
                    this.imageBasePath = Path.GetFullPath(Path.Combine(this.imageFolder, this.imageBasePath));
                }

                if (!Directory.Exists(this.exportBasePath))
                {
                    Directory.CreateDirectory(this.exportBasePath);
                }

                using (this.inputDatabase = new Database(inputPath, OpenDatabase.ReadOnly))
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (StreamWriter streamWriter = new StreamWriter(memoryStream, Encoding.UTF8))
                        {
                            writer = new XmlTextWriter(streamWriter);

                            // use indenting for readability
                            writer.Formatting = Formatting.Indented;

                            this.core = new DecompilerCore(writer, this.Message);
                            this.core.AddComments = this.addComments;

                            // process the reader into the writer
                            try
                            {
                                foreach (DecompilerExtension extension in this.extensionList)
                                {
                                    extension.Core = this.core;

                                    extension.Messages = this.extensionMessages;
                                    extension.InitializeDecompile();
                                }

                                // do the actual processing to an internal buffer
                                this.ProcessProductElement(true);
                            }

                            // throw an exception
                            catch (XmlException e)
                            {
                                // todo: throw a real exception
                                throw e;
                            }

                            // if no error was found, save the result to the specified file
                            if (!this.foundError)
                            {
                                writer.Flush();

                                using (FileStream fileStream = File.Create(outputPath))
                                {
                                    memoryStream.WriteTo(fileStream);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                if (null != writer)
                {
                    writer.Close();
                    writer = null;
                }

                foreach (XmlWriter fragmentWriter in this.openFragments.Values)
                {
                    fragmentWriter.Close();
                }

                this.inputDatabase = null;
                this.outputFolder = null;

                if (!this.tidy)
                {
                    Console.WriteLine("Tidy set to false; files can be found at '{0}'.", this.extractFolder);
                }
                else
                {
                    this.DeleteTempFiles(this.extractFolder);
                }
            }
        }