Fixed some UI layout stuff.

This commit is contained in:
2026-06-01 15:26:47 +02:00
parent 076504753e
commit 27299fc8e7
3 changed files with 105 additions and 22 deletions
+3
View File
@@ -35,6 +35,8 @@ Das BizTalk Platform Management Tool unterstützt kontrollierte Wartungsfenster
8. Nach der Wartung mit **Restore** aus `before.json` wiederherstellen.
9. Mit **Snapshot After** und **Compare** die Umgebung validieren.
Die Statusanzeige rechts im Kopfbereich bewertet die Host-Instance-Zustaende des letzten Snapshots und zeigt `Started`, `Stopped`, `Partial` oder `Unknown`. **Clear** leert die sichtbaren Ergebnis- und Log-Grids, loescht aber keine Dateien. **Close** beendet die Anwendung.
## Sicherheitsdesign
- Dry-run ist standardmäßig aktiviert.
@@ -42,6 +44,7 @@ Das BizTalk Platform Management Tool unterstützt kontrollierte Wartungsfenster
- Jede Operation schreibt Einträge in das sichtbare Operation Log.
- Zusätzlich wird neben der EXE eine tägliche Logdatei `BizTalkPlatformManagementTool-yyyy-MM-dd.log` geschrieben.
- Logdateien werden rollierend für den aktuellen Tag plus vier vorherige Tage vorgehalten.
- Der Kopfbereich zeigt den zuletzt erkannten Umgebungsstatus aus den Host Instances.
- Operationspläne werden vor Laufzeitänderungen gespeichert.
- WMI-Methodenrückgaben werden geprüft.
- Wartezeiten nutzen konfigurierbare Timeout- und Polling-Werte.
+4
View File
@@ -21,6 +21,8 @@ WinForms tool for controlled Microsoft BizTalk Server 2020 platform operations d
- Dry-run mode enabled by default
- WMI access through `root\MicrosoftBizTalkServer`
- Detailed operation logging in the GUI and daily rolling log files next to the executable
- Environment status indicator based on host instance state
- Clear and Close actions in the main toolbar
- No compile-time dependency on BizTalk ExplorerOM assemblies
## Safe Usage
@@ -34,6 +36,8 @@ WinForms tool for controlled Microsoft BizTalk Server 2020 platform operations d
7. After maintenance, click **Restore** using the saved `before.json`.
8. Click **Snapshot After** and **Compare**.
The environment indicator shows `Started`, `Stopped`, `Partial` or `Unknown` from the most recent snapshot. `Clear` removes the visible status and operation log grids; it does not delete files.
## Operation Order
Shutdown:
@@ -1,6 +1,7 @@
using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using BizTalkPlatformManagementTool.Models;
@@ -20,6 +21,7 @@ namespace BizTalkPlatformManagementTool.Ui
private readonly DataGridView _logGrid = new DataGridView();
private readonly StatusStrip _statusStrip = new StatusStrip();
private readonly ToolStripStatusLabel _statusLabel = new ToolStripStatusLabel();
private readonly Label _environmentStatusLabel = new Label();
private readonly OperationLogger _logger;
private readonly BizTalkOperationService _service;
@@ -29,6 +31,8 @@ namespace BizTalkPlatformManagementTool.Ui
private Button _compareButton;
private Button _shutdownButton;
private Button _restoreButton;
private Button _clearButton;
private Button _closeButton;
public MainForm()
{
@@ -53,7 +57,7 @@ namespace BizTalkPlatformManagementTool.Ui
RowCount = 4,
Padding = new Padding(10)
};
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 88));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 92));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 54));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 24));
@@ -70,42 +74,52 @@ namespace BizTalkPlatformManagementTool.Ui
private Control BuildSettingsPanel()
{
var panel = new TableLayoutPanel { Dock = DockStyle.Fill, ColumnCount = 8, RowCount = 2 };
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 70));
var panel = new TableLayoutPanel { Dock = DockStyle.Fill, ColumnCount = 10, RowCount = 2 };
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 30));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 45));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 96));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 70));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 76));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 35));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 88));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 82));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 88));
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 36));
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 36));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 76));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 220));
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 40));
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 40));
_serverTextBox.Text = Environment.MachineName;
_serverTextBox.Dock = DockStyle.Fill;
ConfigureInput(_serverTextBox);
_outputTextBox.Text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "BizTalkPlatformManagementTool");
_outputTextBox.Dock = DockStyle.Fill;
ConfigureInput(_outputTextBox);
_stateFileTextBox.Text = "before.json";
_stateFileTextBox.Dock = DockStyle.Fill;
ConfigureInput(_stateFileTextBox);
_timeoutInput.Minimum = 30;
_timeoutInput.Maximum = 3600;
_timeoutInput.Value = 300;
_timeoutInput.Dock = DockStyle.Fill;
ConfigureInput(_timeoutInput);
_pollInput.Minimum = 1;
_pollInput.Maximum = 60;
_pollInput.Value = 5;
_pollInput.Dock = DockStyle.Fill;
ConfigureInput(_pollInput);
_dryRunCheckBox.Text = "Dry run";
_dryRunCheckBox.Checked = true;
_dryRunCheckBox.Dock = DockStyle.Fill;
_dryRunCheckBox.Margin = new Padding(8, 7, 8, 7);
_dryRunCheckBox.TextAlign = ContentAlignment.MiddleLeft;
var browseButton = new Button { Text = "Browse...", Dock = DockStyle.Fill };
var browseButton = new Button { Text = "Browse...", Dock = DockStyle.Fill, Margin = new Padding(8, 5, 8, 5) };
browseButton.Click += BrowseButtonClick;
_environmentStatusLabel.Dock = DockStyle.Fill;
_environmentStatusLabel.Margin = new Padding(12, 5, 0, 5);
_environmentStatusLabel.TextAlign = ContentAlignment.MiddleCenter;
_environmentStatusLabel.BorderStyle = BorderStyle.FixedSingle;
UpdateEnvironmentStatus(null);
panel.Controls.Add(Label("Server"), 0, 0);
panel.Controls.Add(_serverTextBox, 1, 0);
panel.Controls.Add(Label("Output"), 2, 0);
@@ -116,23 +130,27 @@ namespace BizTalkPlatformManagementTool.Ui
panel.Controls.Add(Label("State"), 0, 1);
panel.Controls.Add(_stateFileTextBox, 1, 1);
panel.SetColumnSpan(_stateFileTextBox, 3);
panel.Controls.Add(_dryRunCheckBox, 4, 1);
panel.Controls.Add(Label("Poll sec."), 5, 1);
panel.Controls.Add(_pollInput, 6, 1);
panel.SetColumnSpan(_stateFileTextBox, 2);
panel.Controls.Add(_dryRunCheckBox, 3, 1);
panel.Controls.Add(Label("Poll sec."), 7, 1);
panel.Controls.Add(_pollInput, 8, 1);
panel.Controls.Add(_environmentStatusLabel, 9, 0);
panel.SetRowSpan(_environmentStatusLabel, 2);
return panel;
}
private Control BuildActionPanel()
{
var panel = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.LeftToRight, Padding = new Padding(0, 8, 0, 0) };
var panel = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.LeftToRight, Padding = new Padding(0, 8, 0, 0), WrapContents = false };
_diagnoseButton = ActionButton("Diagnose", DiagnoseClick);
_beforeButton = ActionButton("Snapshot Before", BeforeClick);
_afterButton = ActionButton("Snapshot After", AfterClick);
_compareButton = ActionButton("Compare", CompareClick);
_shutdownButton = ActionButton("Shutdown", ShutdownClick);
_restoreButton = ActionButton("Restore", RestoreClick);
_clearButton = ActionButton("Clear", ClearClick);
_closeButton = ActionButton("Close", CloseClick);
panel.Controls.Add(_diagnoseButton);
panel.Controls.Add(_beforeButton);
@@ -140,6 +158,8 @@ namespace BizTalkPlatformManagementTool.Ui
panel.Controls.Add(_compareButton);
panel.Controls.Add(_shutdownButton);
panel.Controls.Add(_restoreButton);
panel.Controls.Add(_clearButton);
panel.Controls.Add(_closeButton);
return panel;
}
@@ -259,6 +279,19 @@ namespace BizTalkPlatformManagementTool.Ui
});
}
private void ClearClick(object sender, EventArgs e)
{
_statusGrid.Rows.Clear();
_logGrid.Rows.Clear();
UpdateEnvironmentStatus(null);
_statusLabel.Text = "Ready.";
}
private void CloseClick(object sender, EventArgs e)
{
Close();
}
private void RunAsync(string status, Action work)
{
SetBusy(true, status);
@@ -342,6 +375,7 @@ namespace BizTalkPlatformManagementTool.Ui
{
_statusGrid.Rows.Add("HostInstance", string.Empty, item.InstanceName, item.StateText, item.HostName + " on " + item.Server);
}
UpdateEnvironmentStatus(snapshot);
});
}
@@ -405,6 +439,8 @@ namespace BizTalkPlatformManagementTool.Ui
_compareButton.Enabled = !busy;
_shutdownButton.Enabled = !busy;
_restoreButton.Enabled = !busy;
_clearButton.Enabled = !busy;
_closeButton.Enabled = !busy;
_statusLabel.Text = status;
});
}
@@ -440,16 +476,56 @@ namespace BizTalkPlatformManagementTool.Ui
private static Label Label(string text)
{
return new Label { Text = text, Dock = DockStyle.Fill, TextAlign = ContentAlignment.MiddleLeft };
return new Label { Text = text, Dock = DockStyle.Fill, TextAlign = ContentAlignment.MiddleRight, Margin = new Padding(0, 5, 4, 5) };
}
private static Button ActionButton(string text, EventHandler handler)
{
var button = new Button { Text = text, Width = 148, Height = 34, Margin = new Padding(0, 0, 8, 0) };
var button = new Button { Text = text, Width = 112, Height = 34, Margin = new Padding(0, 0, 8, 0) };
button.Click += handler;
return button;
}
private static void ConfigureInput(Control control)
{
control.Dock = DockStyle.Fill;
control.Margin = new Padding(4, 6, 8, 6);
}
private void UpdateEnvironmentStatus(BizTalkSnapshot snapshot)
{
if (snapshot == null || snapshot.HostInstances == null || snapshot.HostInstances.Count == 0)
{
_environmentStatusLabel.Text = "Environment: Unknown";
_environmentStatusLabel.BackColor = SystemColors.Control;
_environmentStatusLabel.ForeColor = SystemColors.ControlText;
return;
}
var total = snapshot.HostInstances.Count;
var started = snapshot.HostInstances.Count(x => x.RawState == ArtifactStates.HostStarted);
var pending = snapshot.HostInstances.Count(x => x.RawState == ArtifactStates.HostStartPending || x.RawState == ArtifactStates.HostStopPending);
if (started == total)
{
_environmentStatusLabel.Text = "Environment: Started (" + started + "/" + total + ")";
_environmentStatusLabel.BackColor = Color.FromArgb(230, 245, 233);
_environmentStatusLabel.ForeColor = Color.DarkGreen;
}
else if (started == 0 && pending == 0)
{
_environmentStatusLabel.Text = "Environment: Stopped (0/" + total + ")";
_environmentStatusLabel.BackColor = Color.FromArgb(252, 232, 230);
_environmentStatusLabel.ForeColor = Color.DarkRed;
}
else
{
_environmentStatusLabel.Text = "Environment: Partial (" + started + "/" + total + ")";
_environmentStatusLabel.BackColor = Color.FromArgb(255, 244, 214);
_environmentStatusLabel.ForeColor = Color.DarkOrange;
}
}
private static void ConfigureGrid(DataGridView grid)
{
grid.Dock = DockStyle.Fill;