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))); }
/// <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)); }
/// <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); } }
/// <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); }
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(); }
/// <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; } } }
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)); }
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 }); }
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); }
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)); }
/// <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; }
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); } }
/// <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); }
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); } } }
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; } }
/// <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); } }
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)); }