From 54a9f22c874476f23aec301383e0ddddf2f97664 Mon Sep 17 00:00:00 2001 From: Danilo Del Busso Date: Wed, 10 Aug 2022 15:44:07 +0100 Subject: [PATCH] CP-39929: Add timestamps to update logs - Add option to the display options page - Add related setting - Refactor `ExtensionMethods` to be more compact and flexible - Add docs to `ExtensionMethods` - Whitespace fixes Signed-off-by: Danilo Del Busso --- XenAdmin/Core/ExtensionMethods.cs | 123 +++++++++++++----- .../DisplayOptionsPage.Designer.cs | 34 +++++ .../OptionsPages/DisplayOptionsPage.cs | 11 +- .../OptionsPages/DisplayOptionsPage.resx | 122 ++++++++++++++++- XenAdmin/Properties/Settings.Designer.cs | 13 ++ XenAdmin/Properties/Settings.settings | 3 + .../AutomatedUpdatesBasePage.cs | 43 +++--- .../PatchingWizard/PatchingWizard_ModePage.cs | 2 +- XenAdmin/app.config | 3 + 9 files changed, 290 insertions(+), 64 deletions(-) diff --git a/XenAdmin/Core/ExtensionMethods.cs b/XenAdmin/Core/ExtensionMethods.cs index 8b78ffa3e..d0ac8f061 100644 --- a/XenAdmin/Core/ExtensionMethods.cs +++ b/XenAdmin/Core/ExtensionMethods.cs @@ -29,30 +29,32 @@ * SUCH DAMAGE. */ -using System.Drawing; +using System; +using System.Drawing; +using System.Linq; using System.Text; using System.Windows.Forms; - namespace XenAdmin.Core { - internal static class ExtensionMethods - { - /// - /// Internationalization of True/False - /// - public static string ToStringI18n(this bool value) - { - return value ? Messages.TRUE : Messages.FALSE; - } + internal static class ExtensionMethods + { + private const int DEFAULT_STRING_INDENTATION = 2; + /// + /// Internationalization of True/False + /// + public static string ToStringI18n(this bool value) + { + return value ? Messages.TRUE : Messages.FALSE; + } - /// - /// Turns a bool to internationalized Yes/No (on occasion it's user friendlier than True/False) - /// - public static string ToYesNoStringI18n(this bool value) - { - return value ? Messages.YES : Messages.NO; - } + /// + /// Turns a bool to internationalized Yes/No (on occasion it's user friendlier than True/False) + /// + public static string ToYesNoStringI18n(this bool value) + { + return value ? Messages.YES : Messages.NO; + } /// /// This has the same bahvoiur as the standard ellipsise extension but this uses graphics @@ -88,24 +90,79 @@ namespace XenAdmin.Core return text.Ellipsise(c); } - public static StringBuilder AppendIndented(this StringBuilder builder, string value, int indent = 2) + /// + /// Append the input value after it's been prepended with the specified amount of spaces. + /// If the value spans multiple lines, each line will be indented. + /// + /// The to which the modified value will be appended. + /// The value to prepend with spaces and then append. + /// The amount of spaces to prepend to each line in the input value. + /// The input after the operation has been completed. + public static StringBuilder AppendIndented(this StringBuilder builder, string value, int indent = DEFAULT_STRING_INDENTATION) { - var indentString = ""; - var i = 0; - while (i++ < indent) - indentString += " "; - var newvalue = value.Replace(System.Environment.NewLine, string.Format("{0}{1}", System.Environment.NewLine, indentString)); - return builder.Append(string.Format("{0}{1}", indentString, newvalue)); + return builder.Append(PrependIndentation(value, indent)); } - public static StringBuilder AppendIndented(this StringBuilder builder, StringBuilder value, int indent = 2) + /// + /// Add a new line to the input , with options to format the input value before it's appended. + /// + /// The to which the modified value will be appended. + /// The value to format before appending. + /// true if each line should be prepended with a timestamp + /// true if each line should be prepended with indentation. Uses the default indentation defined in : + /// true to append an extra line. + /// The input after the operation has been completed. + public static StringBuilder AppendFormattedLine(this StringBuilder builder, string value, bool addTimestamp = false, bool indent = false, bool addExtraLine = false) { - var indentString = ""; - var i = 0; - while (i++ < indent) - indentString += " "; - var newvalue = value.Replace(System.Environment.NewLine, string.Format("{0}{1}", System.Environment.NewLine, indentString)); - return builder.Append(string.Format("{0}{1}", indentString, newvalue)); + var formattedValue = value; + if (!string.IsNullOrEmpty(value)) + { + if (indent) + { + formattedValue = PrependIndentation(formattedValue); + } + if (addTimestamp) + { + formattedValue = PrependTimestamps(formattedValue); + } + } + + builder.AppendLine(formattedValue); + + if (addExtraLine) + { + builder.AppendLine(); + } + + return builder; } - } + + /// + /// Prepend every line in the input value with the specified indentation level. + /// + /// The value to which indentation will be applied + /// The level of indentation, i.e. the number of spaces to prepend to every line in the value. + /// The input value with prepended indentation./ + private static string PrependIndentation(string value, int indent = DEFAULT_STRING_INDENTATION) + { + var indentString = new string(' ', indent); + var newValue = value.Replace(Environment.NewLine, $"{Environment.NewLine}{indentString}"); + return $"{indentString}{newValue}"; + } + + /// + /// Prepend every line in the input value with a formatted string of . + /// + /// The input value + /// true to format the string with the user's locale + /// The input value with prepended timestamps/ + public static string PrependTimestamps(string value, bool localize = true) + { + var timestamp = DateTime.Now; + var timestampString = HelpersGUI.DateTimeToString(timestamp, Messages.DATEFORMAT_HMS, localize); + // normalise all line endings before splitting + var lines = value.Replace(Environment.NewLine, "\n").Split('\n'); + return string.Join(Environment.NewLine, lines.Select(line => $"{timestampString}> {line}")); + } + } } diff --git a/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.Designer.cs b/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.Designer.cs index 71ee5c90e..a548e15fa 100644 --- a/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.Designer.cs +++ b/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.Designer.cs @@ -30,6 +30,9 @@ namespace XenAdmin.Dialogs.OptionsPages { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DisplayOptionsPage)); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.updateLogOptionsDecentGroupBox = new XenAdmin.Controls.DecentGroupBox(); + this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); + this.showTimestampsCheckBox = new System.Windows.Forms.CheckBox(); this.GraphTypeGroupBox = new XenAdmin.Controls.DecentGroupBox(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.label5 = new XenAdmin.Controls.Common.AutoHeightLabel(); @@ -41,6 +44,8 @@ namespace XenAdmin.Dialogs.OptionsPages this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.checkBoxStoreTab = new System.Windows.Forms.CheckBox(); this.tableLayoutPanel3.SuspendLayout(); + this.updateLogOptionsDecentGroupBox.SuspendLayout(); + this.tableLayoutPanel4.SuspendLayout(); this.GraphTypeGroupBox.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); @@ -52,10 +57,32 @@ namespace XenAdmin.Dialogs.OptionsPages // tableLayoutPanel3 // resources.ApplyResources(this.tableLayoutPanel3, "tableLayoutPanel3"); + this.tableLayoutPanel3.Controls.Add(this.updateLogOptionsDecentGroupBox, 0, 2); this.tableLayoutPanel3.Controls.Add(this.GraphTypeGroupBox, 0, 0); this.tableLayoutPanel3.Controls.Add(this.TabGroupBox, 0, 1); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; // + // updateLogOptionsDecentGroupBox + // + resources.ApplyResources(this.updateLogOptionsDecentGroupBox, "updateLogOptionsDecentGroupBox"); + this.updateLogOptionsDecentGroupBox.Controls.Add(this.tableLayoutPanel4); + this.updateLogOptionsDecentGroupBox.Name = "updateLogOptionsDecentGroupBox"; + this.updateLogOptionsDecentGroupBox.TabStop = false; + // + // tableLayoutPanel4 + // + resources.ApplyResources(this.tableLayoutPanel4, "tableLayoutPanel4"); + this.tableLayoutPanel4.Controls.Add(this.showTimestampsCheckBox, 0, 0); + this.tableLayoutPanel4.Name = "tableLayoutPanel4"; + // + // showTimestampsCheckBox + // + resources.ApplyResources(this.showTimestampsCheckBox, "showTimestampsCheckBox"); + this.showTimestampsCheckBox.Checked = true; + this.showTimestampsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.showTimestampsCheckBox.Name = "showTimestampsCheckBox"; + this.showTimestampsCheckBox.UseVisualStyleBackColor = true; + // // GraphTypeGroupBox // resources.ApplyResources(this.GraphTypeGroupBox, "GraphTypeGroupBox"); @@ -135,6 +162,10 @@ namespace XenAdmin.Dialogs.OptionsPages this.Name = "DisplayOptionsPage"; this.tableLayoutPanel3.ResumeLayout(false); this.tableLayoutPanel3.PerformLayout(); + this.updateLogOptionsDecentGroupBox.ResumeLayout(false); + this.updateLogOptionsDecentGroupBox.PerformLayout(); + this.tableLayoutPanel4.ResumeLayout(false); + this.tableLayoutPanel4.PerformLayout(); this.GraphTypeGroupBox.ResumeLayout(false); this.GraphTypeGroupBox.PerformLayout(); this.tableLayoutPanel1.ResumeLayout(false); @@ -163,5 +194,8 @@ namespace XenAdmin.Dialogs.OptionsPages private System.Windows.Forms.PictureBox pictureBox2; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.CheckBox checkBoxStoreTab; + private Controls.DecentGroupBox updateLogOptionsDecentGroupBox; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; + private System.Windows.Forms.CheckBox showTimestampsCheckBox; } } diff --git a/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.cs b/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.cs index 13f0fc1cc..e0ac00725 100644 --- a/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.cs +++ b/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.cs @@ -48,6 +48,7 @@ namespace XenAdmin.Dialogs.OptionsPages GraphAreasRadioButton.Checked = Properties.Settings.Default.FillAreaUnderGraphs; GraphLinesRadioButton.Checked = !Properties.Settings.Default.FillAreaUnderGraphs; checkBoxStoreTab.Checked = Properties.Settings.Default.RememberLastSelectedTab; + showTimestampsCheckBox.Checked = Properties.Settings.Default.ShowTimestampsInUpdatesLog; } #region IOptionsPage Members @@ -59,20 +60,24 @@ namespace XenAdmin.Dialogs.OptionsPages public void ShowValidationMessages() { + // no message } public void HideValidationMessages() { + // no message } public void Save() { if (GraphAreasRadioButton.Checked != Properties.Settings.Default.FillAreaUnderGraphs) - Properties.Settings.Default.FillAreaUnderGraphs = GraphAreasRadioButton.Checked; - + Properties.Settings.Default.FillAreaUnderGraphs = GraphAreasRadioButton.Checked; + if (checkBoxStoreTab.Checked != Properties.Settings.Default.RememberLastSelectedTab) Properties.Settings.Default.RememberLastSelectedTab = checkBoxStoreTab.Checked; - + + if (showTimestampsCheckBox.Checked != Properties.Settings.Default.ShowTimestampsInUpdatesLog) + Properties.Settings.Default.ShowTimestampsInUpdatesLog = showTimestampsCheckBox.Checked; } #endregion diff --git a/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.resx b/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.resx index 2664f1322..4ef7a1716 100644 --- a/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.resx +++ b/XenAdmin/Dialogs/OptionsPages/DisplayOptionsPage.resx @@ -128,6 +128,115 @@ 1 + + True + + + GrowAndShrink + + + True + + + 1 + + + True + + + NoControl + + + + 3, 3 + + + 3, 0, 0, 0 + + + 201, 17 + + + 0 + + + Show timestamps in the update logs + + + showTimestampsCheckBox + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel4 + + + 0 + + + Fill + + + 3, 16 + + + 1 + + + 617, 49 + + + 0 + + + tableLayoutPanel4 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + updateLogOptionsDecentGroupBox + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="showTimestampsCheckBox" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,Absolute,49,Absolute,49,Absolute,49" /></TableLayoutSettings> + + + Fill + + + Tahoma, 8pt + + + 3, 337 + + + 3, 3, 3, 6 + + + 623, 71 + + + 2 + + + Update logs options + + + updateLogOptionsDecentGroupBox + + + XenAdmin.Controls.DecentGroupBox, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + + + tableLayoutPanel3 + + + 0 + True @@ -146,7 +255,6 @@ Fill - Tahoma, 8pt @@ -172,7 +280,7 @@ label5 - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + XenAdmin.Controls.Common.AutoHeightLabel, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null tableLayoutPanel1 @@ -373,13 +481,13 @@ GraphTypeGroupBox - XenAdmin.Controls.DecentGroupBox, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + XenAdmin.Controls.DecentGroupBox, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null tableLayoutPanel3 - 0 + 1 True @@ -481,13 +589,13 @@ TabGroupBox - XenAdmin.Controls.DecentGroupBox, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + XenAdmin.Controls.DecentGroupBox, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null tableLayoutPanel3 - 1 + 2 Fill @@ -520,7 +628,7 @@ 0 - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="GraphTypeGroupBox" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="TabGroupBox" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,Percent,100,Absolute,20,Absolute,20,Absolute,20" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="updateLogOptionsDecentGroupBox" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="GraphTypeGroupBox" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="TabGroupBox" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,Percent,100,Absolute,20,Absolute,20,Absolute,20" /></TableLayoutSettings> True diff --git a/XenAdmin/Properties/Settings.Designer.cs b/XenAdmin/Properties/Settings.Designer.cs index caa5c85d0..85b5356c0 100644 --- a/XenAdmin/Properties/Settings.Designer.cs +++ b/XenAdmin/Properties/Settings.Designer.cs @@ -865,5 +865,18 @@ namespace XenAdmin.Properties { this["IgnoreFirstRunWizards"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] + public bool ShowTimestampsInUpdatesLog { + get { + return ((bool)(this["ShowTimestampsInUpdatesLog"])); + } + set { + this["ShowTimestampsInUpdatesLog"] = value; + } + } } } diff --git a/XenAdmin/Properties/Settings.settings b/XenAdmin/Properties/Settings.settings index f01698ef2..e66868097 100644 --- a/XenAdmin/Properties/Settings.settings +++ b/XenAdmin/Properties/Settings.settings @@ -200,5 +200,8 @@ <?xml version="1.0" encoding="utf-16"?> <ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" /> + + True + \ No newline at end of file diff --git a/XenAdmin/Wizards/PatchingWizard/AutomatedUpdatesBasePage.cs b/XenAdmin/Wizards/PatchingWizard/AutomatedUpdatesBasePage.cs index c7988b413..c1ff2915b 100644 --- a/XenAdmin/Wizards/PatchingWizard/AutomatedUpdatesBasePage.cs +++ b/XenAdmin/Wizards/PatchingWizard/AutomatedUpdatesBasePage.cs @@ -97,7 +97,8 @@ namespace XenAdmin.Wizards.PatchingWizard return; using (var dialog = new WarningDialog(ReconsiderCancellationMessage(), - ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo){WindowTitle = Text}) + ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo) + { WindowTitle = Text }) { if (dialog.ShowDialog(this) != DialogResult.Yes) { @@ -164,7 +165,7 @@ namespace XenAdmin.Wizards.PatchingWizard _backgroundWorkers = new List(); _failedWorkers = new List(); var atLeastOneWorkerStarted = false; - + foreach (var pool in SelectedPools) { var planActions = GenerateHostPlans(pool, out _); @@ -253,10 +254,12 @@ namespace XenAdmin.Wizards.PatchingWizard newVal = 0; else if (newVal > 100) newVal = 100; - progressBar.Value = (int) newVal; + progressBar.Value = (int)newVal; var stringBuilder = new StringBuilder(); + var addTimestamp = Properties.Settings.Default.ShowTimestampsInUpdatesLog; + foreach (var bgw in _backgroundWorkers) { var bgwErrorCount = 0; @@ -265,13 +268,13 @@ namespace XenAdmin.Wizards.PatchingWizard var errorSb = new StringBuilder(); if (!string.IsNullOrEmpty(bgw.Name)) - sb.AppendLine($"{bgw.Name}:"); + sb.AppendFormattedLine($"{bgw.Name}:", addTimestamp); foreach (var pa in bgw.DoneActions) { - pa.ProgressHistory.ForEach(step => sb.AppendIndented(step).AppendLine()); + pa.ProgressHistory.ForEach(step => sb.AppendFormattedLine(step, addTimestamp, true)); - if (pa.Error == null) + if (pa.Error == null) continue; if (pa.Error is CancelledException) @@ -279,14 +282,12 @@ namespace XenAdmin.Wizards.PatchingWizard bgwCancellationCount++; continue; } - - errorSb.AppendLine(!(pa.Error.InnerException is Failure innerEx) ? pa.Error.Message : innerEx.Message); + errorSb.AppendFormattedLine(!(pa.Error.InnerException is Failure innerEx) ? pa.Error.Message : innerEx.Message, addTimestamp, true, true); if (pa.IsSkippable) { Debug.Assert(!string.IsNullOrEmpty(pa.Title)); - errorSb.AppendLine(string.Format(Messages.RPU_WIZARD_ERROR_SKIP_MSG, pa.Title)) - .AppendLine(); + errorSb.AppendFormattedLine(string.Format(Messages.RPU_WIZARD_ERROR_SKIP_MSG, pa.Title), addTimestamp, true, true); } bgwErrorCount++; @@ -294,23 +295,25 @@ namespace XenAdmin.Wizards.PatchingWizard foreach (var pa in bgw.InProgressActions) { - pa.ProgressHistory.ForEach(step => sb.AppendIndented(step).AppendLine()); + pa.ProgressHistory.ForEach(step => sb.AppendFormattedLine(step, addTimestamp, true)); } sb.AppendLine(); if (bgwCancellationCount > 0) { - sb.AppendIndented(UserCancellationMessage()).AppendLine(); + sb.AppendFormattedLine(UserCancellationMessage(), addTimestamp, indent: true); } else if (bgwErrorCount > 0) { - sb.AppendIndented(FailureMessagePerPool(bgwErrorCount > 1)).AppendLine(); - sb.AppendIndented(errorSb); + sb.AppendFormattedLine(FailureMessagePerPool(bgwErrorCount > 1), addTimestamp, true); + + // we don't add formatting since errorSb has its own + sb.Append(errorSb.ToString()); } else if (!bgw.IsBusy) { - sb.AppendIndented(WarningMessagePerPool(bgw.Pool) ?? SuccessMessagePerPool(bgw.Pool)).AppendLine(); + sb.AppendFormattedLine(WarningMessagePerPool(bgw.Pool) ?? SuccessMessagePerPool(bgw.Pool), addTimestamp, true); } sb.AppendLine(); @@ -318,7 +321,7 @@ namespace XenAdmin.Wizards.PatchingWizard } var newText = stringBuilder.ToString(); - + if (!_userMovedVerticalScrollbar) { textBoxLog.Text = newText; @@ -361,7 +364,7 @@ namespace XenAdmin.Wizards.PatchingWizard // Step 2: UpdatesPlanActions (priority update action) bgw.ProgressIncrement = bgw.UpdatesActionsIncrement(hp); - var planActions = hp.UpdatesPlanActions; + var planActions = hp.UpdatesPlanActions; foreach (var a in planActions) { action = a; @@ -539,7 +542,7 @@ namespace XenAdmin.Wizards.PatchingWizard using (var dlg = new WarningDialog(string.Format(skippableWorkers.Count > 1 ? Messages.MESSAGEBOX_SKIP_RPU_STEPS : Messages.MESSAGEBOX_SKIP_RPU_STEP, msg), ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo) - {WindowTitle = ParentForm != null ? ParentForm.Text : BrandManager.BrandConsole}) + { WindowTitle = ParentForm != null ? ParentForm.Text : BrandManager.BrandConsole }) { if (dlg.ShowDialog(this) != DialogResult.Yes) return; @@ -578,7 +581,7 @@ namespace XenAdmin.Wizards.PatchingWizard } } #endregion - + protected HostPlan GetUpdatePlanActionsForHost(Host host, List hosts, List minimalPatches, List uploadedPatches, KeyValuePair patchFromDisk, bool repatriateVms = true) { @@ -651,7 +654,7 @@ namespace XenAdmin.Wizards.PatchingWizard ?? planActionsPerHost.FindLast(a => a is RestartHostPlanAction); if (lastRestart != null) - ((RestartHostPlanAction) lastRestart).EnableOnly = false; + ((RestartHostPlanAction)lastRestart).EnableOnly = false; } return new HostPlan(host, null, planActionsPerHost, delayedActionsPerHost); diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs index 254464d59..71fc1710c 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs @@ -106,7 +106,7 @@ namespace XenAdmin.Wizards.PatchingWizard foreach (var kvp in ManualTextInstructions) { sb.AppendFormat("{0}:", kvp.Key).AppendLine(); - sb.AppendIndented(kvp.Value).AppendLine(); + sb.AppendIndented(kvp.Value.ToString()).AppendLine(); } textBoxLog.Text = sb.ToString(); } diff --git a/XenAdmin/app.config b/XenAdmin/app.config index e19e3d7ff..1613544d4 100644 --- a/XenAdmin/app.config +++ b/XenAdmin/app.config @@ -195,6 +195,9 @@ + + True +