Beispiel #1
0
        /// <summary>
        /// Gets the <see cref="Installation"/> class given the <see cref="Parameters"/>.
        /// </summary>
        /// <param name="param">The <see cref="Parameters"/> of the <see cref="Installation"/> to get.</param>
        /// <returns>An <see cref="Installation"/> given the <see cref="Parameters"/>.</returns>
        protected Installation GetInstallation(Parameters param)
        {
            Installation installation = null;

            try
            {
                if (string.IsNullOrEmpty(param.PatchCode))
                {
                    installation = ProductInstallation.GetProducts(param.ProductCode, param.UserSid, param.UserContext).FirstOrDefault();
                }
                else
                {
                    installation = PatchInstallation.GetPatches(param.PatchCode, param.ProductCode, param.UserSid, param.UserContext, PatchStates.All).FirstOrDefault();
                }
            }
            catch (InstallerException ex)
            {
                var pse = new PSInstallerException(ex);
                if (null != pse.ErrorRecord)
                {
                    base.WriteError(pse.ErrorRecord);
                }
            }

            return(installation);
        }
Beispiel #2
0
        /// <summary>
        /// Writes and error to the pipeline.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing the error details.</param>
        /// <returns>The result code indicating how Windows Installer should proceed.</returns>
        protected MessageResult OnError(Deployment.WindowsInstaller.Record record)
        {
            if (null == record)
            {
                return(MessageResult.None);
            }
            else if (0 < record.FieldCount)
            {
                // Ignore certain errors.
                int code = record.GetInteger(1);
                switch (code)
                {
                case 1605:
                    // Continue even if there isn't enough disk space for rollback.
                    return(MessageResult.Ignore);

                case 1704:
                    // Roll back suspended installs so we can continue.
                    return(MessageResult.OK);
                }
            }

            using (var ex = new PSInstallerException(record))
            {
                if (null != ex.ErrorRecord)
                {
                    this.WriteError(ex.ErrorRecord);
                }
            }

            return(MessageResult.OK);
        }
Beispiel #3
0
        /// <summary>
        /// Applies any applicable transforms from <see cref="Patch"/> and <see cref="Transform"/> to the given package.
        /// </summary>
        /// <param name="db">The <see cref="InstallPackage"/> database to which applicable transforms are applied.</param>
        protected void ApplyTransforms(InstallPackage db)
        {
            // Apply transforms first since they likely apply to the unpatched product.
            if (0 < this.Transform.Count())
            {
                this.Transform = this.ResolveFiles(this.Transform).ToArray();

                foreach (string path in this.Transform)
                {
                    try
                    {
                        db.ApplyTransform(path, PatchApplicator.IgnoreErrors);
                        db.ApplyTransform(path, PatchApplicator.IgnoreErrors | TransformErrors.ViewTransform);
                    }
                    catch (InstallerException ex)
                    {
                        using (var pse = new PSInstallerException(ex))
                        {
                            if (null != pse.ErrorRecord)
                            {
                                base.WriteError(pse.ErrorRecord);
                            }
                        }
                    }
                }

                db.Commit();
            }

            // Apply applicable patch transforms.
            if (0 < this.Patch.Count())
            {
                this.Patch = this.ResolveFiles(this.Patch).ToArray();

                var applicator = new PatchApplicator(db);
                foreach (string path in this.Patch)
                {
                    applicator.Add(path);
                }

                applicator.InapplicablePatch += (source, args) =>
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_InapplicablePatch, args.Patch, args.Product);
                    base.WriteVerbose(message);
                };

                // The applicator will commit the changes.
                applicator.Apply();
            }
        }
Beispiel #4
0
        private MessageResult OnError(Deployment.WindowsInstaller.Record record)
        {
            if (null != record)
            {
                using (var ex = new PSInstallerException(record))
                {
                    if (null != ex.ErrorRecord)
                    {
                        var data = new Data(DataType.Error, ex.ErrorRecord);
                        this.Output.Enqueue(data);
                    }
                }
            }

            return(MessageResult.OK);
        }
Beispiel #5
0
        /// <summary>
        /// Processes the input paths and writes the file hashes to the pipeline.
        /// </summary>
        protected override void ProcessRecord()
        {
            // If no path was provided, enumerate all child items.
            if (null == this.Path || 0 == this.Path.Length)
            {
                this.Path = All;
            }

            // Enumerate all the file system items.
            var items = this.InvokeProvider.Item.Get(this.Path, true, this.IsLiteralPath);

            foreach (var item in items)
            {
                // Get the provider path.
                var path = item.GetPropertyValue <string>("PSPath");
                path = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);

                if (File.Exists(path) || Directory.Exists(path))
                {
                    try
                    {
                        this.ProcessItem(item);
                    }
                    catch (InstallerException ex)
                    {
                        var pse = new PSInstallerException(ex);
                        if (null != pse.ErrorRecord)
                        {
                            base.WriteError(pse.ErrorRecord);
                        }
                    }
                }
                else
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Error_InvalidFile, path);
                    var ex      = new NotSupportedException(message);
                    var error   = new ErrorRecord(ex, "UnsupportedItemType", ErrorCategory.InvalidType, path);

                    this.WriteError(error);
                }
            }
        }
Beispiel #6
0
        private void ExecuteActions()
        {
            using (new UserInterfaceHandler(this.OnMessage, this.Force))
            {
                // Keep track of the total weight for all queued actions.
                this.Actions.OriginalWeight = this.Actions.Sum(data => data.Weight);

                // Create a single restore point for chained packages.
                SystemRestorePoint restorePoint = null;
                if (this.Chain)
                {
                    try
                    {
                        restorePoint = SystemRestorePoint.Create(this.Operation);
                    }
                    catch (Win32Exception ex)
                    {
                        var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_NoRestorePoint, ex.Message);
                        this.WriteWarning(message);
                    }
                }

                // Execute the actions.
                while (0 < this.Actions.Count)
                {
                    try
                    {
                        T data = this.Actions.Dequeue();
                        this.progress.CurrentWeight = data.Weight;

                        string extra = null != data ? data.LogName : null;
                        Installer.EnableLog(this.log.Mode, this.log.Next(extra));

                        // If a system restore point was successfully created,
                        // disable creating restore points for each package.
                        if (null != restorePoint)
                        {
                            data.CommandLine += " MSIFASTINSTALL=1";
                        }

                        // Suppress reboots when possible if chaining.
                        if (this.Chain)
                        {
                            data.CommandLine += " REBOOT=ReallySuppress";
                        }

                        this.ExecuteAction(data);
                    }
                    catch (InstallerException ex)
                    {
                        using (var psiex = new PSInstallerException(ex))
                        {
                            if (null != psiex.ErrorRecord)
                            {
                                this.WriteError(psiex.ErrorRecord);
                            }
                            else
                            {
                                // Unexpected not to have an ErrorRecord.
                                throw;
                            }
                        }
                    }
                    finally
                    {
                        if (null != this.result)
                        {
                            this.result.RebootInitiated = Installer.RebootInitiated;
                            this.result.RebootRequired  = Installer.RebootRequired;
                        }
                    }
                }

                // Complete an existing restore point.
                if (null != restorePoint)
                {
                    restorePoint.Commit();
                }

                // Make sure progress is completed.
                this.WriteProgress(true);

                // Warn the user if a restart is required.
                if (Installer.RebootRequired)
                {
                    var ex = new Win32Exception(3010);
                    this.WriteWarning(ex.Message);
                }
            }
        }
Beispiel #7
0
        private MessageResult OnError(Deployment.WindowsInstaller.Record record)
        {
            if (null != record)
            {
                using (var ex = new PSInstallerException(record))
                {
                    if (null != ex.ErrorRecord)
                    {
                        var data = new Data(DataType.Error, ex.ErrorRecord);
                        this.Output.Enqueue(data);
                    }
                }
            }

            return MessageResult.OK;
        }
Beispiel #8
0
        /// <summary>
        /// Merges ICE cubes into the database <paramref name="item"/> and executes selected ICEs.
        /// </summary>
        /// <param name="item">The database to validate.</param>
        protected override void ProcessItem(PSObject item)
        {
            // Get the item path and set the current context.
            string path = item.GetPropertyValue<string>("PSPath");
            path = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);
            this.CurrentPath = path;

            // Copy the database to a writable location and open.
            string copy = this.Copy(path);
            using (var db = new InstallPackage(copy, DatabaseOpenMode.Direct))
            {
                // Apply any patches or transforms before otherwise modifying.
                this.ApplyTransforms(db);

                // Copy the ProductCode and drop the Property table to avoid opening an installed product.
                bool hasProperty = db.IsTablePersistent("Property");
                string productCode = null;

                if (hasProperty)
                {
                    productCode = db.ExecutePropertyQuery("ProductCode");
                }

                // Merge the ICE cubes and fix up the database if needed.
                this.MergeCubes(db);
                if (!hasProperty)
                {
                    db.Execute("DROP TABLE `Property`");
                }

                var included = new List<WildcardPattern>();
                if (null != this.Include)
                {
                    Array.ForEach(this.Include, pattern => included.Add(new WildcardPattern(pattern)));
                }

                var excluded = new List<WildcardPattern>();
                if (null != this.Exclude)
                {
                    Array.ForEach(this.Exclude, pattern => excluded.Add(new WildcardPattern(pattern)));
                }

                // Get all the ICE actions in the database that are not excluded.
                var actions = new List<string>();
                foreach (var action in db.ExecuteStringQuery("SELECT `Action` FROM `_ICESequence` ORDER BY `Sequence`"))
                {
                    if (!action.Match(excluded))
                    {
                        actions.Add(action);
                    }
                }

                // Remove any actions not explicitly included.
                if (0 < included.Count)
                {
                    for (int i = actions.Count - 1; 0 <= i; --i)
                    {
                        if (!actions[i].Match(included))
                        {
                            actions.RemoveAt(i);
                        }
                    }
                }

                // Open a session with the database.
                using (var session = Installer.OpenPackage(db, false))
                {
                    // Put the original ProductCode back.
                    if (!string.IsNullOrEmpty(productCode))
                    {
                        db.Execute("DELETE FROM `Property` WHERE `Property` = 'ProductCode'");
                        db.Execute("INSERT INTO `Property` (`Property`, `Value`) VALUES ('ProductCode', '{0}')", productCode);
                    }

                    // Now execute all the remaining actions in order.
                    foreach (string action in actions)
                    {
                        try
                        {
                            session.DoAction(action);
                            this.Flush();
                        }
                        catch (InstallerException ex)
                        {
                            using (var pse = new PSInstallerException(ex))
                            {
                                if (null != pse.ErrorRecord)
                                {
                                    this.WriteError(pse.ErrorRecord);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Processes the input paths and writes the file hashes to the pipeline.
        /// </summary>
        protected override void ProcessRecord()
        {
            // If no path was provided, enumerate all child items.
            if (null == this.Path || 0 == this.Path.Length)
            {
                this.Path = All;
            }

            // Enumerate all the file system items.
            var items = this.InvokeProvider.Item.Get(this.Path, true, this.IsLiteralPath);
            foreach (var item in items)
            {
                // Get the provider path.
                var path = item.GetPropertyValue<string>("PSPath");
                path = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);

                if (File.Exists(path) || Directory.Exists(path))
                {
                    try
                    {
                        this.ProcessItem(item);
                    }
                    catch (InstallerException ex)
                    {
                        var pse = new PSInstallerException(ex);
                        if (null != pse.ErrorRecord)
                        {
                            base.WriteError(pse.ErrorRecord);
                        }
                    }
                }
                else
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Error_InvalidFile, path);
                    var ex = new NotSupportedException(message);
                    var error = new ErrorRecord(ex, "UnsupportedItemType", ErrorCategory.InvalidType, path);

                    this.WriteError(error);
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Merges ICE cubes into the database <paramref name="item"/> and executes selected ICEs.
        /// </summary>
        /// <param name="item">The database to validate.</param>
        protected override void ProcessItem(PSObject item)
        {
            // Get the item path and set the current context.
            string path = item.GetPropertyValue <string>("PSPath");

            path             = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);
            this.CurrentPath = path;

            // Copy the database to a writable location and open.
            string copy = this.Copy(path);

            using (var db = new InstallPackage(copy, DatabaseOpenMode.Direct))
            {
                // Apply any patches or transforms before otherwise modifying.
                this.ApplyTransforms(db);

                // Copy the ProductCode and drop the Property table to avoid opening an installed product.
                bool   hasProperty = db.IsTablePersistent("Property");
                string productCode = null;

                if (hasProperty)
                {
                    productCode = db.ExecutePropertyQuery("ProductCode");
                }

                // Merge the ICE cubes and fix up the database if needed.
                this.MergeCubes(db);
                if (!hasProperty)
                {
                    db.Execute("DROP TABLE `Property`");
                }

                var included = new List <WildcardPattern>();
                if (null != this.Include)
                {
                    Array.ForEach(this.Include, pattern => included.Add(new WildcardPattern(pattern)));
                }

                var excluded = new List <WildcardPattern>();
                if (null != this.Exclude)
                {
                    Array.ForEach(this.Exclude, pattern => excluded.Add(new WildcardPattern(pattern)));
                }

                // Get all the ICE actions in the database that are not excluded.
                var actions = new List <string>();
                foreach (var action in db.ExecuteStringQuery("SELECT `Action` FROM `_ICESequence` ORDER BY `Sequence`"))
                {
                    if (!action.Match(excluded))
                    {
                        actions.Add(action);
                    }
                }

                // Remove any actions not explicitly included.
                if (0 < included.Count)
                {
                    for (int i = actions.Count - 1; 0 <= i; --i)
                    {
                        if (!actions[i].Match(included))
                        {
                            actions.RemoveAt(i);
                        }
                    }
                }

                // Open a session with the database.
                using (var session = Installer.OpenPackage(db, false))
                {
                    // Put the original ProductCode back.
                    if (!string.IsNullOrEmpty(productCode))
                    {
                        db.Execute("DELETE FROM `Property` WHERE `Property` = 'ProductCode'");
                        db.Execute("INSERT INTO `Property` (`Property`, `Value`) VALUES ('ProductCode', '{0}')", productCode);
                    }

                    // Now execute all the remaining actions in order.
                    foreach (string action in actions)
                    {
                        try
                        {
                            session.DoAction(action);
                            this.Flush();
                        }
                        catch (InstallerException ex)
                        {
                            using (var pse = new PSInstallerException(ex))
                            {
                                if (null != pse.ErrorRecord)
                                {
                                    this.WriteError(pse.ErrorRecord);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Applies any applicable transforms from <see cref="Patch"/> and <see cref="Transform"/> to the given package.
        /// </summary>
        /// <param name="db">The <see cref="InstallPackage"/> database to which applicable transforms are applied.</param>
        protected void ApplyTransforms(InstallPackage db)
        {
            // Apply transforms first since they likely apply to the unpatched product.
            if (0 < this.Transform.Count())
            {
                this.Transform = this.ResolveFiles(this.Transform).ToArray();

                foreach (string path in this.Transform)
                {
                    try
                    {
                        db.ApplyTransform(path, PatchApplicator.IgnoreErrors);
                        db.ApplyTransform(path, PatchApplicator.IgnoreErrors | TransformErrors.ViewTransform);
                    }
                    catch (InstallerException ex)
                    {
                        using (var pse = new PSInstallerException(ex))
                        {
                            if (null != pse.ErrorRecord)
                            {
                                base.WriteError(pse.ErrorRecord);
                            }
                        }
                    }
                }

                db.Commit();
            }

            // Apply applicable patch transforms.
            if (0 < this.Patch.Count())
            {
                this.Patch = this.ResolveFiles(this.Patch).ToArray();

                var applicator = new PatchApplicator(db);
                foreach (string path in this.Patch)
                {
                    applicator.Add(path);
                }

                applicator.InapplicablePatch += (source, args) =>
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_InapplicablePatch, args.Patch, args.Product);
                    base.WriteVerbose(message);
                };

                // The applicator will commit the changes.
                applicator.Apply();
            }
        }