Esempio n. 1
0
        public string[] GetNodes(InventoryDataLoadStatusCallback statusCallback)
        {
            ArrayList nodes = new ArrayList();

            statusCallback(nodes.Count, @"Products\...\Patches");
            foreach (ProductInstallation product in ProductInstallation.AllProducts)
            {
                string productName = MsiUtils.GetProductName(product.ProductCode);

                bool addedRoot = false;
                foreach (PatchInstallation productPatch in PatchInstallation.GetPatches(null, product.ProductCode, null, UserContexts.All, PatchStates.Applied))
                {
                    if (!addedRoot)
                    {
                        nodes.Add(String.Format(@"Products\{0}\Patches", productName));
                    }
                    nodes.Add(String.Format(@"Products\{0}\Patches\{1}", productName, productPatch.PatchCode));
                }
            }

            statusCallback(nodes.Count, "Patches");

            string[] allPatches = GetAllPatchesList();
            if (allPatches.Length > 0)
            {
                nodes.Add("Patches");
                foreach (string patchCode in allPatches)
                {
                    nodes.Add(String.Format(@"Patches\{0}", patchCode));
                    nodes.Add(String.Format(@"Patches\{0}\Patched Products", patchCode));
                }
                statusCallback(nodes.Count, String.Empty);
            }
            return((string[])nodes.ToArray(typeof(string)));
        }
Esempio n. 2
0
        /// <summary>
        /// Returns true if given patch is uninstalled from all the target products
        /// </summary>
        /// <param name="patchCode"></param>
        /// <param name="targetProdCodes"></param>
        /// <returns></returns>
        public static bool IsPatchUninstalled(string patchCode, string[] targetProdCodes)
        {
            bool found = true;

            foreach (string targetProdCode in targetProdCodes)
            {
                // Exclude the patch verification for those products which are not installed
                if (!MsiUtils.IsProductInstalled(targetProdCode))
                {
                    continue;
                }

                foreach (PatchInstallation patch in PatchInstallation.GetPatches(patchCode, targetProdCode, null, UserContexts.All, PatchStates.All))
                {
                    if (patch.PatchCode == patchCode)
                    {
                        found = false;
                    }
                }

                // Return after first occurance of found. That is it will return false if patch is applied to any of the target products.
                if (!found)
                {
                    return(found);
                }
            }
            return(found);
        }
        public static bool IsPatchAlreadyInstalled(string productCode, string patchCode)
        {
            var patches =
                PatchInstallation.GetPatches(null, productCode, null, UserContexts.Machine, PatchStates.Applied);

            return(patches.Any(patch => patch.DisplayName == patchCode));
        }
Esempio n. 4
0
 /// <summary>
 /// Enumerates patches for the given patch codes and ProductCodes and writes them to the pipeline.
 /// </summary>
 /// <param name="patchCode">The patch code to enumerate.</param>
 /// <param name="productCode">The ProductCode having patches to enumerate.</param>
 /// <param name="userSid">The user's SID for patches to enumerate.</param>
 /// <param name="context">The installation context for patches to enumerate.</param>
 /// <param name="filter">The patch installation state for patches to enumerate.</param>
 private void WritePatches(string patchCode, string productCode, string userSid, UserContexts context, PatchStates filter)
 {
     foreach (PatchInstallation patch in PatchInstallation.GetPatches(patchCode, productCode, userSid, context, filter))
     {
         this.WritePatch(patch);
     }
 }
Esempio n. 5
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);
        }
Esempio n. 6
0
 internal DCSPatchInstallation(IStatusReportNotify parent, string patchSet, string patchSetShortName)
 {
     _parent           = parent;
     PatchSet          = patchSet;
     PatchSetShortName = patchSetShortName;
     Patching          = new PatchInstallation(LoadDestinations(Locations),
                                               PatchSet,
                                               $"Helios {PatchSetShortName} patches");
     Patching.PatchesChanged += Patching_PatchesChanged;
     SubscribeToLocationChanges();
 }
Esempio n. 7
0
        /// <summary>
        /// Writes a source information to the pipeline.
        /// </summary>
        /// <param name="installation">The <see cref="Installation"/> to which the source is registered.</param>
        protected void WriteSourceList(Installation installation)
        {
            ProductInstallation product = null;
            PatchInstallation   patch   = null;
            var order = 0;

            if (installation is ProductInstallation)
            {
                product = (ProductInstallation)installation;
            }
            else if (installation is PatchInstallation)
            {
                patch = (PatchInstallation)installation;
            }

            try
            {
                foreach (var source in installation.SourceList)
                {
                    SourceInfo info = null;
                    if (null != product)
                    {
                        info = new SourceInfo(product.ProductCode, product.UserSid, product.Context, source, order++);
                    }
                    else if (null != patch)
                    {
                        info = new PatchSourceInfo(patch.ProductCode, patch.PatchCode, patch.UserSid, patch.Context, source, order++);
                    }

                    if (null != info)
                    {
                        this.WriteObject(info);
                    }
                }
            }
            catch (InstallerException ex)
            {
                if (NativeMethods.ERROR_BAD_CONFIGURATION == ex.ErrorCode)
                {
                    var code      = null != product ? product.ProductCode : null != patch ? patch.PatchCode : string.Empty;
                    var message   = string.Format(Properties.Resources.Error_Corrupt, code);
                    var exception = new Exception(message, ex);

                    var error = new ErrorRecord(exception, "Error_Corrupt", ErrorCategory.NotInstalled, installation);
                    base.WriteError(error);
                }
                else
                {
                    throw;
                }
            }
        }
Esempio n. 8
0
        private DataView GetProductPatchData(string productCode)
        {
            DataTable table = new DataTable("ProductPatches");

            table.Locale = CultureInfo.InvariantCulture;
            table.Columns.Add("ProductPatchesPatchCode", typeof(string));

            foreach (PatchInstallation patch in PatchInstallation.GetPatches(null, productCode, null, UserContexts.All, PatchStates.Applied))
            {
                table.Rows.Add(new object[] { patch.PatchCode });
            }
            return(new DataView(table, "", "ProductPatchesPatchCode ASC", DataViewRowState.CurrentRows));
        }
Esempio n. 9
0
        public override IEnumerable <StatusReportItem> PerformReadyCheck()
        {
            // load patchExclusions from settings instead of caching them, so we don't have different code paths from elevated binary
            HashSet <string> patchExclusions = PatchInstallation.LoadPatchExclusions();

            // check if DCS install folders are configured
            IList <InstallationLocation> locations = InstallationLocations.Singleton.Active;

            if (!locations.Any())
            {
                yield return(new StatusReportItem
                {
                    Status = $"No DCS installation locations are configured for {PatchSetShortName} patch installation",
                    Recommendation = "Configure any DCS installation directories you use",
                    Link = StatusReportItem.ProfileEditor,
                    Severity = StatusReportItem.SeverityCode.Error
                });

                yield break;
            }

            // check if all our patches are installed
            foreach (PatchApplication item in locations
                     .Select(CreatePatchDestination))
            {
                if (item.SelectedVersion == null)
                {
                    yield return(new StatusReportItem
                    {
                        Status = $"No {PatchSetShortName} patches compatible with {item.Destination.Description} found",
                        Recommendation =
                            "Please reinstall Helios to install these patches or provide them in documents folder",
                        Severity = StatusReportItem.SeverityCode.Error
                    });
                }

                foreach (StatusReportItem result in item.Patches.Verify(item.Destination, patchExclusions))
                {
                    // return detailed results instead of just "up to date or not"
                    yield return(result);
                }
            }

            yield return(new StatusReportItem
            {
                Status = $"Helios is managing DCS {PatchSetShortName} patches",
                Recommendation =
                    $"Do not also install {PatchSetShortName} mods manually or via a mod manager like OVGME",
                Flags = StatusReportItem.StatusFlags.Verbose | StatusReportItem.StatusFlags.ConfigurationUpToDate
            });
        }
Esempio n. 10
0
        private static void DcsRevert(ElevatedProcessResponsePipe response, string outputRoot, IEnumerable <string> patchFolders)
        {
            PatchList patches = LoadPatches(patchFolders);

            if (!InstallationLocation.TryLoadLocation(outputRoot, true, out InstallationLocation location))
            {
                ReportBadLocation(response, outputRoot);
                return;
            }
            PatchDestination         dcs             = new PatchDestination(location);
            HashSet <string>         patchExclusions = PatchInstallation.LoadPatchExclusions();
            IList <StatusReportItem> results         = patches.Revert(dcs, patchExclusions).ToList();

            response.SendReport(results);
        }
Esempio n. 11
0
        private DataView GetPatchTargetData(string patchCode)
        {
            DataTable table = new DataTable("PatchTargets");

            table.Locale = CultureInfo.InvariantCulture;
            table.Columns.Add("PatchTargetsProductName", typeof(string));
            table.Columns.Add("PatchTargetsProductCode", typeof(string));

            foreach (PatchInstallation patch in PatchInstallation.GetPatches(patchCode, null, null, UserContexts.All, PatchStates.Applied))
            {
                if (patch.PatchCode == patchCode)
                {
                    string productName = MsiUtils.GetProductName(patch.ProductCode);
                    table.Rows.Add(new object[] { productName, patch.ProductCode });
                }
            }
            return(new DataView(table, "", "PatchTargetsProductName ASC", DataViewRowState.CurrentRows));
        }
Esempio n. 12
0
        /// <summary>
        /// Returns a <see cref="PSObject"/> wrapper for a <see cref="PatchInstallation"/> object and attaches special properties.
        /// </summary>
        /// <param name="source">The <see cref="PatchInstallation"/> object to convert.</param>
        /// <param name="provider">A <see cref="PathIntrinsics"/> provider used to convert paths.</param>
        /// <returns>A <see cref="PSObject"/> wrapper with attached special properties.</returns>
        internal static PSObject ToPSObject(this PatchInstallation source, PathIntrinsics provider = null)
        {
            if (null == source)
            {
                throw new ArgumentNullException("source");
            }

            var obj = PSObject.AsPSObject(source);

            // Add path information if possible.
            if (null != provider)
            {
                var path = provider.GetUnresolvedPSPathFromProviderPath(source.LocalPackage);
                obj.SetPropertyValue<string>("PSPath", path);
            }

            return obj;
        }
Esempio n. 13
0
        private static void AddRow(ProductInstallation p)
        {
            myRow r = new myRow(p);

            rows.Add(r);
            Logger.LogMsg(r.ToString());

            try
            {
                IEnumerable <PatchInstallation> patches = PatchInstallation.GetPatches(null, p.ProductCode, null, UserContexts.All, PatchStates.All);



                foreach (PatchInstallation patch in patches)
                {
                    myRow patchRow = new myRow(patch);
                    rows.Add(patchRow);
                    Logger.LogMsg(patchRow.ToString());
                }
            }catch (Exception ex)
            {
                Logger.LogError("AddRow:" + ex.Message);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Adds properties to the <see cref="PatchInstallation"/> object and writes it to the pipeline.
        /// </summary>
        /// <param name="patch">The <see cref="PatchInstallation"/> to write to the pipeline.</param>
        private void WritePatch(PatchInstallation patch)
        {
            var obj = patch.ToPSObject(this.SessionState.Path);

            this.WriteObject(obj);
        }
Esempio n. 15
0
        public static void GetAllProducts()
        {
            var allPrds = ProductInstallation.GetProducts(null, null, UserContexts.All);

            int i = 0;

            if (isFilterOn && filterString != "")
            {
                root.Text = System.Environment.MachineName + " filtered by \"" + filterString + "\"";
            }
            else
            {
                root.Text = System.Environment.MachineName;
            }
            foreach (ProductInstallation p in allPrds)
            {
                // if (string.IsNullOrEmpty(p.ProductName)) continue;
                if (isFilterOn && filterString != "")
                {
                    if (string.IsNullOrEmpty(p.ProductName))
                    {
                        continue;
                    }
                    else if (!p.ProductName.ToLower().Contains(filterString.ToLower()))
                    {
                        continue;
                    }
                }
                try
                {
                    UpdateProgress("Processing (" + i + ") " + p.ProductName);
                    i++; //if (i > 40) break;
                    TreeNode node = new TreeNode(p.ProductName);
                    node.Name = p.ProductName;
                    root.Nodes.Add(node);
                    TreeNode nodeProp = new TreeNode("Properties");
                    node.Nodes.Add(nodeProp);
                    try
                    {
                        AddProductProperty(nodeProp, p);
                    }
                    catch (Exception ex)
                    {
                        TreeNode error = new TreeNode(ex.Message);
                        nodeProp.Nodes.Add(error);
                        Logger.LogError(p.ProductName + ":" + ex.Message);
                    }


                    List <PatchInstallation> patches = PatchInstallation.GetPatches(null, p.ProductCode, null, UserContexts.All, PatchStates.All).ToList();
                    if (patches.Count > 0)
                    {
                        TreeNode pa = new TreeNode("Patches");
                        node.Nodes.Add(pa);
                        foreach (PatchInstallation pch in patches)
                        {
                            TreeNode nd = new TreeNode(pch.DisplayName);
                            nd.Name = pch.DisplayName;
                            pa.Nodes.Add(nd);

                            try
                            {
                                AddPatchProperty(nd, pch);
                            }
                            catch (Exception ex)
                            {
                                TreeNode error = new TreeNode(ex.Message);
                                nd.Nodes.Add(error);
                                Logger.LogError(pch.DisplayName + ":" + ex.Message);
                            }
                        }
                    }

                    if (p.Features != null)
                    {
                        List <FeatureInstallation> lst = p.Features.ToList();
                        if (lst.Count > 0)
                        {
                            TreeNode pa = new TreeNode("Features");
                            node.Nodes.Add(pa);

                            foreach (FeatureInstallation fi in lst)
                            {
                                string   txt = "FeatureName : " + fi.FeatureName + "; State : " + fi.State.ToString();
                                TreeNode nd  = new TreeNode(txt);
                                nd.Name = nd.Text;
                                pa.Nodes.Add(nd);
                                nd.ImageIndex         = 1;
                                nd.SelectedImageIndex = 1;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError("GetAllProducts:ProductCode:" + p.ProductCode + "\n" + ex.Message);
                }
            }
        }
Esempio n. 16
0
        public static void AddPatchProperty(TreeNode node, PatchInstallation p)
        {
            TreeNode nd = new TreeNode("DisplayName : " + p.DisplayName);

            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;
            nd.Name = nd.Text;
            node.Nodes.Add(nd);

            nd                    = new TreeNode("InstallDate : " + p.InstallDate);
            nd.Name               = nd.Text;
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            node.Nodes.Add(nd);


            nd                    = new TreeNode("IsInstalled : " + p.IsInstalled);
            nd.Name               = nd.Text;
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            node.Nodes.Add(nd);

            nd                    = new TreeNode("IsObsoleted : " + p.IsObsoleted);
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            nd.Name = nd.Text;
            node.Nodes.Add(nd);

            nd                    = new TreeNode("IsSuperseded : " + p.IsSuperseded);
            nd.Name               = nd.Text;
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            node.Nodes.Add(nd);


            nd                    = new TreeNode("LocalPackage : " + p.LocalPackage);
            nd.Name               = nd.Text;
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            node.Nodes.Add(nd);

            nd                    = new TreeNode("PatchCode : " + p.PatchCode);
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            nd.Name = nd.Text;
            node.Nodes.Add(nd);

            nd                    = new TreeNode("ProductCode : " + p.ProductCode);
            nd.Name               = nd.Text;
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            node.Nodes.Add(nd);


            nd                    = new TreeNode("Transforms : " + p.Transforms);
            nd.Name               = nd.Text;
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            node.Nodes.Add(nd);

            nd                    = new TreeNode("Uninstallable : " + p.Uninstallable);
            nd.ImageIndex         = 1;
            nd.SelectedImageIndex = 1;

            nd.Name = nd.Text;
            node.Nodes.Add(nd);


            if (p.SourceList != null)
            {
                nd      = new TreeNode("SourceList");
                nd.Name = nd.Text;
                node.Nodes.Add(nd);

                TreeNode ndkid = new TreeNode("PackageName : " + p.SourceList.PackageName);
                ndkid.Name               = ndkid.Text;
                ndkid.ImageIndex         = 1;
                ndkid.SelectedImageIndex = 1;

                nd.Nodes.Add(ndkid);

                ndkid                    = new TreeNode("LastUsedSource : " + p.SourceList.LastUsedSource);
                ndkid.Name               = ndkid.Text;
                ndkid.ImageIndex         = 1;
                ndkid.SelectedImageIndex = 1;

                nd.Nodes.Add(ndkid);


                ndkid                    = new TreeNode("MediaPackagePath : " + p.SourceList.MediaPackagePath);
                ndkid.Name               = ndkid.Text;
                ndkid.ImageIndex         = 1;
                ndkid.SelectedImageIndex = 1;

                nd.Nodes.Add(ndkid);
            }
            else
            {
                nd      = new TreeNode("SourceList : ");
                nd.Name = nd.Text;
                node.Nodes.Add(nd);
                nd.ImageIndex         = 1;
                nd.SelectedImageIndex = 1;
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Add row for MSP package
        /// </summary>
        /// <param name="p"></param>
        public myRow(PatchInstallation p)
        {
            this.Index = myData.Index++;

            try
            {
                if (!string.IsNullOrEmpty(p.PatchCode))
                {
                    this.PatchCode = p.PatchCode;
                }

                CacheFileStatus stat = CacheFileStatus.Missing;
                if (!String.IsNullOrEmpty(p.LocalPackage))
                {
                    if (File.Exists(p.LocalPackage))
                    {
                        try
                        {
                            string cachePatchCode = MSIHelper.GetRevisionNumber(p.LocalPackage);
                            if (!string.IsNullOrEmpty(cachePatchCode) && !string.IsNullOrEmpty(this.PatchCode))
                            {
                                if (string.Compare(this.PatchCode, cachePatchCode, StringComparison.Ordinal) != 0)
                                {
                                    stat         = CacheFileStatus.Mismatched;
                                    this.Comment = "Patch code doesn't matched. cached file has package code:" + cachePatchCode + ", but Installer expected:" + this.PatchCode;
                                }
                            }

                            else //if local package exists, but the cachePatchCode is null, or this.PatchCode is null, set it mismatch

                            {
                                //if both are null, or one is null, set it mismatched
                                if (string.IsNullOrEmpty(cachePatchCode) || string.IsNullOrEmpty(this.PatchCode))
                                {
                                    stat         = CacheFileStatus.Mismatched;
                                    this.Comment = "At least one of the patch codes is null. cached file has package code:" + cachePatchCode + ", Installer one:" + this.PatchCode;
                                }
                            }
                            //String ver = MSIHelper.MspGetMetadata(p.LocalPackage, "BaselineVersion");
                            //if (!String.IsNullOrEmpty(this.ProductVersion))
                            //{
                            //    if (ver != this.ProductVersion)
                            //    {
                            //        stat = CacheFileStatus.Mismatched;
                            //        Comment = p.LocalPackage + ": BaselineVersion in MSP not matched the ProductVersion in its MSI. If SP applied this could be normal.";
                            //    }
                            //}
                            //don't check this. patch code is good enough to check mismatched msp file.

                            /*
                             * if (stat != CacheFileStatus.Mismatched)
                             * {
                             *  String pn = MSIHelper.MspGetMetadata(p.LocalPackage, "DisplayName");
                             *  if (p.DisplayName != pn)
                             *  {
                             *      stat = CacheFileStatus.Mismatched;
                             *      Comment = p.LocalPackage + ": DisplayName not matched! Cached file has DisplayName:[" + pn + "] but Installer expected: [" + p.DisplayName + "]";
                             *  }
                             * }
                             */
                        }
                        catch (Exception ex)
                        {
                            // (any exception) set it to mismatched
                            stat    = CacheFileStatus.Mismatched;
                            Comment = ex.Message;
                            Logger.LogError("[Mismatched MSP check failed]" + p.LocalPackage + " \n" + ex.Message);
                        }

                        if (stat != CacheFileStatus.Mismatched)
                        {
                            stat = CacheFileStatus.OK;
                        }
                    }
                    else
                    {
                        stat    = CacheFileStatus.Missing;
                        Comment = p.LocalPackage + " doesn't exist";
                    }
                }
                else
                {
                    stat = CacheFileStatus.Empty;
                }

                this.Status = stat;

                if (p.SourceList != null)
                {
                    this.PackageName    = p.SourceList.PackageName;
                    this.LastUsedSource = p.SourceList.LastUsedSource;
                }
                this.InstallDate = p.InstallDate;

                //patch doesn't have source
                //this.InstallSource = p.InstallSource;
                //this.IsAdvertised = p.IsAdvertised.ToString();
                this.ProductCode = p.ProductCode;
                this.ProductName = p.DisplayName;
                //patch won't have product version
                // this.ProductVersion = p.ProductVersion.ToString();
                //  this.Publisher = p.Publisher;
                this.isPatch = true;

                if (!String.IsNullOrEmpty(p.LocalPackage))
                {
                    CachedMsiMsp = Path.GetFileName(p.LocalPackage);
                    if (File.Exists(p.LocalPackage))
                    {
                        //    CachedMsiMspVersion = MSIHelper.Get(p.LocalPackage, "ProductVersion").ToString();


                        using (var db = new QDatabase(p.LocalPackage, DatabaseOpenMode.ReadOnly))
                        {
                            //using try catch since some msp doesn't all this properties
                            try { this.CachedMsiMspVersion = db.ExecuteScalar("SELECT `Value` FROM `MsiPatchMetadata` WHERE `Property` = '{0}'", "PatchVersion") as string; } catch { }
                            try { this.PatchBaselineVersion = db.ExecuteScalar("SELECT `Value` FROM `MsiPatchMetadata` WHERE `Property` = '{0}'", "BaselineVersion") as string; } catch { };
                            try { this.MoreInfoURL = db.ExecuteScalar("SELECT `Value` FROM `MsiPatchMetadata` WHERE `Property` = '{0}'", "MoreInfoURL") as string; } catch { };
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.LogError("myRow:patch:" + e.Message);
            }
        }
Esempio n. 18
0
        private DataView GetPatchData(string patchCode)
        {
            DataTable table = new DataTable("PatchProperties");

            table.Locale = CultureInfo.InvariantCulture;
            table.Columns.Add("PatchPropertiesProperty", typeof(string));
            table.Columns.Add("PatchPropertiesValue", typeof(string));

            table.Rows.Add(new object[] { "PatchCode", patchCode });

            PatchInstallation patch = new PatchInstallation(patchCode, null);

            string localPackage = null;

            foreach (string property in new string[]
            {
                "InstallDate",
                "LocalPackage",
                "State",
                "Transforms",
                "Uninstallable",
            })
            {
                try
                {
                    string value = patch[property];
                    table.Rows.Add(new object[] { property, (value != null ? value : "") });
                    if (property == "LocalPackage")
                    {
                        localPackage = value;
                    }
                }
                catch (InstallerException iex)
                {
                    table.Rows.Add(new object[] { property, iex.Message });
                }
                catch (ArgumentException) { }
            }

            if (localPackage != null)
            {
                try
                {
                    using (SummaryInfo patchSummaryInfo = new SummaryInfo(localPackage, false))
                    {
                        table.Rows.Add(new object[] { "Title", patchSummaryInfo.Title });
                        table.Rows.Add(new object[] { "Subject", patchSummaryInfo.Subject });
                        table.Rows.Add(new object[] { "Author", patchSummaryInfo.Author });
                        table.Rows.Add(new object[] { "Comments", patchSummaryInfo.Comments });
                        table.Rows.Add(new object[] { "TargetProductCodes", patchSummaryInfo.Template });
                        string obsoletedPatchCodes = patchSummaryInfo.RevisionNumber.Substring(patchSummaryInfo.RevisionNumber.IndexOf('}') + 1);
                        table.Rows.Add(new object[] { "ObsoletedPatchCodes", obsoletedPatchCodes });
                        table.Rows.Add(new object[] { "TransformNames", patchSummaryInfo.LastSavedBy });
                    }
                }
                catch (InstallerException) { }
                catch (IOException) { }
                catch (SecurityException) { }
            }
            return(new DataView(table, "", "PatchPropertiesProperty ASC", DataViewRowState.CurrentRows));
        }