Пример #1
0
        /// <summary>
        /// Writes a <see cref="SummaryInfo"/> object for each supported file type to the pipeline.
        /// </summary>
        /// <param name="item">A <see cref="PSObject"/> representing the file system object to process.</param>
        protected override void ProcessItem(PSObject item)
        {
            var path = item.GetPropertyValue<string>("PSPath");
            var providerPath = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);

            // Make sure the file exists and is a patch.
            var type = FileInfo.GetFileTypeInternal(providerPath);
            if (FileType.Package == type || FileType.Patch == type || FileType.Transform == type)
            {
                using (var info = new Deployment.WindowsInstaller.SummaryInfo(providerPath, false))
                {
                    var copy = new SummaryInfo(info);
                    var obj = PSObject.AsPSObject(copy);

                    // Add the class type as the first type name.
                    var name = typeof(SummaryInfo).FullName + "#" + type;
                    obj.TypeNames.Insert(0, name);

                    // Attach the original PSPath and write to the pipeline.
                    obj.SetPropertyValue("PSPath", path);
                    this.WriteObject(obj);
                }
            }

            // Enumerate transforms in the patch.
            if (FileType.Patch == type && this.IncludeTransforms)
            {
                using (var patch = new PatchPackage(providerPath))
                {
                    foreach (var transform in patch.GetTransformsInfo(true))
                    {
                        var obj = PSObject.AsPSObject(transform);

                        // Attach the original patch path and write to the pipeline.
                        obj.SetPropertyValue("Patch", providerPath);
                        this.WriteObject(obj);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Gets property records from the item.
        /// </summary>
        /// <param name="item">The item from which properties are retrieved.</param>
        protected override void ProcessItem(PSObject item)
        {
            var path = item.GetPropertyValue<string>("PSPath");
            var providerPath = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);

            var db = this.OpenDatabase(providerPath);
            if (null != db)
            {
                // Keep track of which properties were selected.
                IList<string> properties = null;
                if (this.PassThru)
                {
                    properties = new List<string>();
                }

                using (db)
                {
                    TransformView transform = null;
                    if (db.Tables.Contains(TransformView.TableName))
                    {
                        transform = new TransformView(db);
                    }

                    var table = "Property";
                    if ((db is PatchPackage) && db.Tables.Contains("MsiPatchMetadata"))
                    {
                        table = "MsiPatchMetadata";
                    }

                    var query = string.Format("SELECT `Property`, `Value` FROM `{0}`", table);
                    using (var view = db.OpenView(query))
                    {
                        view.Execute();

                        // Get column information from the view before being disposed.
                        var columns = ViewManager.GetColumns(view);

                        var record = view.Fetch();
                        while (null != record)
                        {
                            using (record)
                            {
                                var name = record.GetString(1);
                                if (0 == this.propertyPatterns.Count() || name.Match(this.propertyPatterns))
                                {
                                    if (this.PassThru)
                                    {
                                        if (0 == item.Properties.Match(name).Count())
                                        {
                                            properties.Add(name);

                                            var property = new PSNoteProperty(name, record.GetString(2));
                                            item.Properties.Add(property, true);
                                        }
                                    }
                                    else
                                    {
                                        // Create a locally cached copy of the record.
                                        var copy = new Record(record, columns, transform, providerPath);
                                        var obj = PSObject.AsPSObject(copy);

                                        // Show only column properties by default.
                                        var memberSet = ViewManager.GetMemberSet(view);
                                        obj.Members.Add(memberSet, true);

                                        base.WriteObject(obj);
                                    }
                                }
                            }

                            record = view.Fetch();
                        }
                    }
                }

                if (this.PassThru)
                {
                    var propertySet = new PSPropertySet("MSIProperties", properties);
                    item.Members.Add(propertySet, true);

                    base.WriteObject(item);
                }
            }
        }
Пример #3
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);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Adds each patch enumerated to the <see cref="PatchSequencer"/> to sequence for each product in <see cref="EndProcessing"/>.
        /// </summary>
        /// <param name="item">A <see cref="PSObject"/> representing the path to a patch package.</param>
        protected override void ProcessItem(PSObject item)
        {
            string path = item.GetPropertyValue<string>("PSPath");
            path = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);

            this.sequencer.Add(path);
        }
Пример #5
0
        /// <summary>
        /// Attempts to open the item in Orca, if installed; otherwise, tries to invoke the "edit" verb on the package.
        /// </summary>
        /// <param name="item">The <see cref="PSObject"/> representing a package to open.</param>
        protected override void ProcessItem(PSObject item)
        {
            string path = item.GetPropertyValue<string>("PSPath");
            path = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);

            // Make sure the item is an MSI or MSP package.
            var type = FileInfo.GetFileTypeInternal(path);
            if (FileType.Package != type && FileType.Patch != type)
            {
                var message = string.Format(CultureInfo.CurrentCulture, Resources.Error_InvalidStorage, path);
                var ex = new PSInvalidOperationException(message);
                this.WriteError(ex.ErrorRecord);

                return;
            }

            var info = new ProcessStartInfo()
            {
                WorkingDirectory = System.IO.Path.GetDirectoryName(path),
            };

            if (!string.IsNullOrEmpty(this.orcaPath))
            {
                // Open in Orca, if installed.
                info.FileName = this.orcaPath;
                info.Arguments = "\"" + path + "\"";
            }
            else
            {
                // Try to use the edit verb instead.
                info.FileName = path;
                info.UseShellExecute = true;
                info.Verb = "edit";
            }

            Process process = null;
            try
            {
                process = Process.Start(info);
                if (this.Wait)
                {
                    process.WaitForExit();
                }
            }
            catch (Exception ex)
            {
                if (ex is InvalidOperationException || ex is Win32Exception)
                {
                    // Likely the "edit" verb is not supported so terminate.
                    var pse = new PSInvalidOperationException(ex.Message, ex);
                    this.ThrowTerminatingError(pse.ErrorRecord);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                if (null != process)
                {
                    process.Dispose();
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Opens the database specified by the <paramref name="item"/> and executes the specified query.
        /// </summary>
        /// <param name="item">A file item that references a package database.</param>
        protected override void ProcessItem(PSObject item)
        {
            var path = item.GetPropertyValue<string>("PSPath");
            var providerPath = this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path);

            var db = base.OpenDatabase(providerPath);
            if (null != db)
            {
                using (db)
                {
                    this.WriteRecords(db, providerPath);
                }
            }
        }