Exemple #1
0
        /// <summary>
        /// Main running method for the application.
        /// </summary>
        /// <param name="args">Commandline arguments to the application.</param>
        /// <returns>Returns the application error code.</returns>
        private int Run(string[] args)
        {
            Microsoft.Tools.WindowsInstallerXml.Binder binder = null;
            Differ   differ   = null;
            Unbinder unbinder = null;

            TempFileCollection tempFileCollection = null;

            try
            {
                // parse the command line
                this.ParseCommandLine(args);

                // validate the inputs
                if (this.xmlInputs && this.adminImage)
                {
                    this.messageHandler.Display(this, WixErrors.IllegalCommandlineArgumentCombination("a", "xi"));
                    this.showHelp = true;
                }

                string[] allValidExtensions               = new string[] { wixMstExtension, wixOutExtension, wixPdbExtension, msiExtension };
                string[] expectedSingleInputExtensions    = new string[] { wixMstExtension, wixOutExtension };
                string[] expectedDoubleInputXmlExtensions = new string[] { wixOutExtension, wixPdbExtension };
                string[] expectedDoubleInputMsiExtensions = new string[] { msiExtension };

                // Validate that all inputs have the correct extension and we dont have too many inputs.
                if (1 == this.inputFiles.Count)
                {
                    string inputFile = this.inputFiles[0];

                    bool hasValidExtension = false;
                    foreach (string extension in expectedSingleInputExtensions)
                    {
                        if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase))
                        {
                            hasValidExtension = true;
                            break;
                        }
                    }

                    if (!hasValidExtension)
                    {
                        bool missingInput = false;

                        // Check if its using an extension that could be valid in other scenarios.
                        foreach (string validExtension in allValidExtensions)
                        {
                            if (String.Equals(Path.GetExtension(inputFile), validExtension, StringComparison.OrdinalIgnoreCase))
                            {
                                this.messageHandler.Display(this, WixErrors.WrongFileExtensionForNumberOfInputs(Path.GetExtension(inputFile), inputFile));
                                missingInput = true;
                                break;
                            }
                        }

                        if (!missingInput)
                        {
                            this.messageHandler.Display(this, WixErrors.UnexpectedFileExtension(inputFile, String.Join(", ", expectedSingleInputExtensions)));
                        }
                    }
                }
                else if (2 == this.inputFiles.Count)
                {
                    foreach (string inputFile in inputFiles)
                    {
                        bool     hasValidExtension  = false;
                        string[] expectedExtensions = allValidExtensions;
                        if (this.xmlInputs)
                        {
                            foreach (string extension in expectedDoubleInputXmlExtensions)
                            {
                                if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase))
                                {
                                    hasValidExtension  = true;
                                    expectedExtensions = expectedDoubleInputXmlExtensions;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            foreach (string extension in expectedDoubleInputMsiExtensions)
                            {
                                if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase))
                                {
                                    hasValidExtension  = true;
                                    expectedExtensions = expectedDoubleInputMsiExtensions;
                                    break;
                                }
                            }
                        }

                        if (!hasValidExtension)
                        {
                            this.messageHandler.Display(this, WixErrors.UnexpectedFileExtension(inputFile, String.Join(", ", expectedExtensions)));
                        }
                    }
                }
                else
                {
                    this.showHelp = true;
                }

                // exit if there was an error parsing the command line or with a file extension (otherwise the logo appears after error messages)
                if (this.messageHandler.EncounteredError)
                {
                    return(this.messageHandler.LastErrorNumber);
                }

                if (null == this.outputFile)
                {
                    this.showHelp = true;
                }

                if (this.showLogo)
                {
                    AppCommon.DisplayToolHeader();
                }

                if (this.showHelp)
                {
                    Console.WriteLine(TorchStrings.HelpMessage);
                    AppCommon.DisplayToolFooter();
                    return(this.messageHandler.LastErrorNumber);
                }

                foreach (string parameter in this.invalidArgs)
                {
                    this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter));
                }
                this.invalidArgs = null;

                binder   = new Microsoft.Tools.WindowsInstallerXml.Binder();
                differ   = new Differ();
                unbinder = new Unbinder();

                // load any extensions
                foreach (string extension in this.extensionList)
                {
                    WixExtension wixExtension = WixExtension.Load(extension);
                    unbinder.AddExtension(wixExtension);
                    binder.AddExtension(wixExtension);
                    differ.AddExtension(wixExtension);
                }

                binder.Message   += new MessageEventHandler(this.messageHandler.Display);
                differ.Message   += new MessageEventHandler(this.messageHandler.Display);
                unbinder.Message += new MessageEventHandler(this.messageHandler.Display);

                binder.TempFilesLocation   = Environment.GetEnvironmentVariable("WIX_TEMP");
                unbinder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP");
                tempFileCollection         = new TempFileCollection(Environment.GetEnvironmentVariable("WIX_TEMP"));

                binder.WixVariableResolver       = new WixVariableResolver();
                differ.PreserveUnchangedRows     = this.preserveUnchangedRows;
                differ.ShowPedanticMessages      = this.showPedanticMessages;
                unbinder.SuppressExtractCabinets = true;
                unbinder.IsAdminImage            = this.adminImage;

                if (null == this.exportBasePath)
                {
                    this.exportBasePath = tempFileCollection.BasePath;
                }

                // load and process the inputs
                Output transform;
                if (1 == this.inputFiles.Count)
                {
                    transform = Output.Load(this.inputFiles[0], false, false);
                    if (OutputType.Transform != transform.Type)
                    {
                        this.messageHandler.Display(this, WixErrors.InvalidWixTransform(this.inputFiles[0]));
                        return(this.messageHandler.LastErrorNumber);
                    }
                }
                else // 2 inputs
                {
                    Output targetOutput;
                    Output updatedOutput;

                    if (this.xmlInputs)
                    {
                        // load the target database
                        if (String.Equals(Path.GetExtension(inputFiles[0]), wixPdbExtension, StringComparison.OrdinalIgnoreCase))
                        {
                            Pdb targetPdb = Pdb.Load(this.inputFiles[0], false, false);
                            targetOutput = targetPdb.Output;
                        }
                        else
                        {
                            targetOutput = Output.Load(this.inputFiles[0], false, false);
                        }

                        // load the updated database
                        if (String.Equals(Path.GetExtension(inputFiles[1]), wixPdbExtension, StringComparison.OrdinalIgnoreCase))
                        {
                            Pdb updatedPdb = Pdb.Load(this.inputFiles[1], false, false);
                            updatedOutput = updatedPdb.Output;
                        }
                        else
                        {
                            updatedOutput = Output.Load(this.inputFiles[1], false, false);
                        }

                        this.xmlOutput = true;
                    }
                    else
                    {
                        // load the target database
                        targetOutput = unbinder.Unbind(this.inputFiles[0], OutputType.Product, Path.Combine(this.exportBasePath, "targetBinaries"));

                        // load the updated database
                        updatedOutput = unbinder.Unbind(this.inputFiles[1], OutputType.Product, Path.Combine(this.exportBasePath, "updatedBinaries"));
                    }

                    // diff the target and updated databases
                    transform = differ.Diff(targetOutput, updatedOutput, this.validationFlags);

                    if (null == transform.Tables || 0 >= transform.Tables.Count)
                    {
                        throw new WixException(WixErrors.NoDifferencesInTransform(transform.SourceLineNumbers));
                    }
                }

                // output the transform
                if (null != transform)
                {
                    // If either the user selected xml output or gave xml input, save as xml output.
                    // With xml inputs, many funtions of the binder have not been performed on the inputs (ie. file sequencing). This results in bad IDT files which cannot be put in a transform.
                    if (this.xmlOutput)
                    {
                        transform.Save(this.outputFile, null, null, tempFileCollection.BasePath);
                    }
                    else
                    {
                        binder.Bind(transform, this.outputFile);
                    }
                }
            }
            catch (WixException we)
            {
                if (we is WixInvalidIdtException)
                {
                    // make sure the IDT files stay around
                    this.tidy = false;
                }

                this.messageHandler.Display(this, we.Error);
            }
            catch (Exception e)
            {
                // make sure the files stay around for debugging
                this.tidy = false;

                this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace));
                if (e is NullReferenceException || e is SEHException)
                {
                    throw;
                }
            }
            finally
            {
                if (null != binder)
                {
                    if (this.tidy)
                    {
                        if (!binder.DeleteTempFiles())
                        {
                            Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, binder.TempFilesLocation);
                        }
                    }
                    else
                    {
                        Console.WriteLine(TorchStrings.INF_BinderTempDirLocatedAt, binder.TempFilesLocation);
                    }
                }

                if (null != unbinder)
                {
                    if (this.tidy)
                    {
                        if (!unbinder.DeleteTempFiles())
                        {
                            Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, binder.TempFilesLocation);
                        }
                    }
                    else
                    {
                        Console.WriteLine(TorchStrings.INF_UnbinderTempDirLocatedAt, binder.TempFilesLocation);
                    }
                }

                if (null != tempFileCollection)
                {
                    if (this.tidy)
                    {
                        try
                        {
                            Directory.Delete(tempFileCollection.BasePath, true);
                        }
                        catch (DirectoryNotFoundException)
                        {
                            // if the path doesn't exist, then there is nothing for us to worry about
                        }
                        catch
                        {
                            Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, tempFileCollection.BasePath);
                        }
                    }
                    else
                    {
                        Console.WriteLine(TorchStrings.INF_TorchTempDirLocatedAt, tempFileCollection.BasePath);
                    }
                }
            }

            return(this.messageHandler.LastErrorNumber);
        }
Exemple #2
0
        /// <summary>
        /// Main running method for the application.
        /// </summary>
        /// <param name="args">Commandline arguments to the application.</param>
        /// <returns>Returns the application error code.</returns>
        private int Run(string[] args)
        {
            Microsoft.Tools.WindowsInstallerXml.Binder binder = null;
            Differ differ = null;
            Unbinder unbinder = null;

            TempFileCollection tempFileCollection = null;

            try
            {
                // parse the command line
                this.ParseCommandLine(args);

                // validate the inputs
                if (this.xmlInputs && this.adminImage)
                {
                    this.messageHandler.Display(this, WixErrors.IllegalCommandlineArgumentCombination("a", "xi"));
                    this.showHelp = true;
                }

                string[] allValidExtensions = new string[] { wixMstExtension, wixOutExtension, wixPdbExtension, msiExtension };
                string[] expectedSingleInputExtensions = new string[] { wixMstExtension, wixOutExtension };
                string[] expectedDoubleInputXmlExtensions = new string[] { wixOutExtension, wixPdbExtension };
                string[] expectedDoubleInputMsiExtensions = new string[] { msiExtension };

                // Validate that all inputs have the correct extension and we dont have too many inputs.
                if (1 == this.inputFiles.Count)
                {
                    string inputFile = this.inputFiles[0];

                    bool hasValidExtension = false;
                    foreach (string extension in expectedSingleInputExtensions)
                    {
                        if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase))
                        {
                            hasValidExtension = true;
                            break;
                        }
                    }

                    if (!hasValidExtension)
                    {
                        bool missingInput = false;

                        // Check if its using an extension that could be valid in other scenarios.
                        foreach (string validExtension in allValidExtensions)
                        {
                            if (String.Equals(Path.GetExtension(inputFile), validExtension, StringComparison.OrdinalIgnoreCase))
                            {
                                this.messageHandler.Display(this, WixErrors.WrongFileExtensionForNumberOfInputs(Path.GetExtension(inputFile), inputFile));
                                missingInput = true;
                                break;
                            }
                        }

                        if (!missingInput)
                        {
                            this.messageHandler.Display(this, WixErrors.UnexpectedFileExtension(inputFile, String.Join(", ", expectedSingleInputExtensions)));
                        }
                    }
                }
                else if (2 == this.inputFiles.Count)
                {
                    foreach (string inputFile in inputFiles)
                    {
                        bool hasValidExtension = false;
                        string[] expectedExtensions = allValidExtensions;
                        if (this.xmlInputs)
                        {
                            foreach (string extension in expectedDoubleInputXmlExtensions)
                            {
                                if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase))
                                {
                                    hasValidExtension = true;
                                    expectedExtensions = expectedDoubleInputXmlExtensions;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            foreach (string extension in expectedDoubleInputMsiExtensions)
                            {
                                if (String.Equals(Path.GetExtension(inputFile), extension, StringComparison.OrdinalIgnoreCase))
                                {
                                    hasValidExtension = true;
                                    expectedExtensions = expectedDoubleInputMsiExtensions;
                                    break;
                                }
                            }
                        }

                        if (!hasValidExtension)
                        {
                            this.messageHandler.Display(this, WixErrors.UnexpectedFileExtension(inputFile, String.Join(", ", expectedExtensions)));
                        }
                    }
                }
                else
                {
                    this.showHelp = true;
                }

                // exit if there was an error parsing the command line or with a file extension (otherwise the logo appears after error messages)
                if (this.messageHandler.EncounteredError)
                {
                    return this.messageHandler.LastErrorNumber;
                }

                if (null == this.outputFile)
                {
                    this.showHelp = true;
                }

                if (this.showLogo)
                {
                    AppCommon.DisplayToolHeader();
                }

                if (this.showHelp)
                {
                    Console.WriteLine(TorchStrings.HelpMessage);
                    AppCommon.DisplayToolFooter();
                    return this.messageHandler.LastErrorNumber;
                }

                foreach (string parameter in this.invalidArgs)
                {
                    this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter));
                }
                this.invalidArgs = null;

                binder = new Microsoft.Tools.WindowsInstallerXml.Binder();
                differ = new Differ();
                unbinder = new Unbinder();

                // load any extensions
                foreach (string extension in this.extensionList)
                {
                    WixExtension wixExtension = WixExtension.Load(extension);
                    unbinder.AddExtension(wixExtension);
                    binder.AddExtension(wixExtension);
                    differ.AddExtension(wixExtension);
                }

                binder.Message += new MessageEventHandler(this.messageHandler.Display);
                differ.Message += new MessageEventHandler(this.messageHandler.Display);
                unbinder.Message += new MessageEventHandler(this.messageHandler.Display);

                binder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP");
                unbinder.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP");
                tempFileCollection = new TempFileCollection(Environment.GetEnvironmentVariable("WIX_TEMP"));

                binder.WixVariableResolver = new WixVariableResolver();
                differ.PreserveUnchangedRows = this.preserveUnchangedRows;
                differ.ShowPedanticMessages = this.showPedanticMessages;
                unbinder.SuppressExtractCabinets = true;
                unbinder.IsAdminImage = this.adminImage;

                if (null == this.exportBasePath)
                {
                    this.exportBasePath = tempFileCollection.BasePath;
                }

                // load and process the inputs
                Output transform;
                if (1 == this.inputFiles.Count)
                {
                    transform = Output.Load(this.inputFiles[0], false, false);
                    if (OutputType.Transform != transform.Type)
                    {
                        this.messageHandler.Display(this, WixErrors.InvalidWixTransform(this.inputFiles[0]));
                        return this.messageHandler.LastErrorNumber;
                    }
                }
                else // 2 inputs
                {
                    Output targetOutput;
                    Output updatedOutput;

                    if (this.xmlInputs)
                    {
                        // load the target database
                        if (String.Equals(Path.GetExtension(inputFiles[0]), wixPdbExtension, StringComparison.OrdinalIgnoreCase))
                        {
                            Pdb targetPdb = Pdb.Load(this.inputFiles[0], false, false);
                            targetOutput = targetPdb.Output;
                        }
                        else
                        {
                            targetOutput = Output.Load(this.inputFiles[0], false, false);
                        }

                        // load the updated database
                        if (String.Equals(Path.GetExtension(inputFiles[1]), wixPdbExtension, StringComparison.OrdinalIgnoreCase))
                        {
                            Pdb updatedPdb = Pdb.Load(this.inputFiles[1], false, false);
                            updatedOutput = updatedPdb.Output;
                        }
                        else
                        {
                            updatedOutput = Output.Load(this.inputFiles[1], false, false);
                        }

                        this.xmlOutput = true;
                    }
                    else
                    {
                        // load the target database
                        targetOutput = unbinder.Unbind(this.inputFiles[0], OutputType.Product, Path.Combine(this.exportBasePath, "targetBinaries"));

                        // load the updated database
                        updatedOutput = unbinder.Unbind(this.inputFiles[1], OutputType.Product, Path.Combine(this.exportBasePath, "updatedBinaries"));
                    }

                    // diff the target and updated databases
                    transform = differ.Diff(targetOutput, updatedOutput, this.validationFlags);

                    if (null == transform.Tables || 0 >= transform.Tables.Count)
                    {
                        throw new WixException(WixErrors.NoDifferencesInTransform(transform.SourceLineNumbers));
                    }
                }

                // output the transform
                if (null != transform)
                {
                    // If either the user selected xml output or gave xml input, save as xml output.
                    // With xml inputs, many funtions of the binder have not been performed on the inputs (ie. file sequencing). This results in bad IDT files which cannot be put in a transform.
                    if (this.xmlOutput)
                    {
                        transform.Save(this.outputFile, null, null, tempFileCollection.BasePath);
                    }
                    else
                    {
                        binder.Bind(transform, this.outputFile);
                    }
                }
            }
            catch (WixException we)
            {
                if (we is WixInvalidIdtException)
                {
                    // make sure the IDT files stay around
                    this.tidy = false;
                }

                this.messageHandler.Display(this, we.Error);
            }
            catch (Exception e)
            {
                // make sure the files stay around for debugging
                this.tidy = false;

                this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace));
                if (e is NullReferenceException || e is SEHException)
                {
                    throw;
                }
            }
            finally
            {
                if (null != binder)
                {
                    if (this.tidy)
                    {
                        if (!binder.DeleteTempFiles())
                        {
                            Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, binder.TempFilesLocation);
                        }
                    }
                    else
                    {
                        Console.WriteLine(TorchStrings.INF_BinderTempDirLocatedAt, binder.TempFilesLocation);
                    }
                }

                if (null != unbinder)
                {
                    if (this.tidy)
                    {
                        if (!unbinder.DeleteTempFiles())
                        {
                            Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, binder.TempFilesLocation);
                        }
                    }
                    else
                    {
                        Console.WriteLine(TorchStrings.INF_UnbinderTempDirLocatedAt, binder.TempFilesLocation);
                    }
                }

                if (null != tempFileCollection)
                {
                    if (this.tidy)
                    {
                        try
                        {
                            Directory.Delete(tempFileCollection.BasePath, true);
                        }
                        catch (DirectoryNotFoundException)
                        {
                            // if the path doesn't exist, then there is nothing for us to worry about
                        }
                        catch
                        {
                            Console.WriteLine(TorchStrings.WAR_FailedToDeleteTempDir, tempFileCollection.BasePath);
                        }
                    }
                    else
                    {
                        Console.WriteLine(TorchStrings.INF_TorchTempDirLocatedAt, tempFileCollection.BasePath);
                    }
                }
            }

            return this.messageHandler.LastErrorNumber;
        }