using Deploymentcenter.Client; namespace Predictalytics.WinFormsHost.Services; /// /// Modal dialog shown at startup when no usable license is present. /// Lets the user enter/activate a license key; closes with OK only after the Deployment /// Center confirmed the activation for this machine. /// public sealed class LicenseDialog : Form { private readonly LicenseClient _client; private readonly Label _lblStatus; private readonly TextBox _txtKey; private readonly Button _btnActivate; private readonly Button _btnExit; /// Set once the activation succeeded. public LicenseSession? Session { get; private set; } public LicenseDialog(LicenseClient client, HardwareIdResult hardware, LicenseValidationResult? lastResult) { _client = client; Text = "Predictalytics — Lizenzaktivierung"; FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; StartPosition = FormStartPosition.CenterScreen; ClientSize = new Size(560, 230); var lblInfo = new Label { Text = "Diese Installation benötigt eine gültige Lizenz.\nBitte Lizenzschlüssel eingeben (Format: XXXXX-XXXXX-XXXXX-XXXXX-XXXXX):", Location = new Point(12, 12), Size = new Size(536, 34) }; _txtKey = new TextBox { Location = new Point(12, 52), Size = new Size(536, 26), Font = new Font("Consolas", 11f), CharacterCasing = CharacterCasing.Upper }; // The hardware ID is what the activation is bound to — without it, support cannot // tell which slot to release when a machine is replaced. var lblHardware = new Label { Text = $"Hardware-ID: {hardware.HardwareId} (Quelle: {hardware.HwidSource})", Location = new Point(12, 84), Size = new Size(536, 20), ForeColor = Color.DimGray, AutoEllipsis = true }; _lblStatus = new Label { Location = new Point(12, 110), Size = new Size(536, 62), ForeColor = Color.Firebrick, Text = FormatInitialStatus(lastResult) }; _btnActivate = new Button { Text = "Aktivieren", Location = new Point(352, 186), Size = new Size(96, 30) }; _btnActivate.Click += async (_, _) => await ActivateAsync(); _btnExit = new Button { Text = "Beenden", Location = new Point(454, 186), Size = new Size(94, 30), DialogResult = DialogResult.Cancel }; AcceptButton = _btnActivate; CancelButton = _btnExit; Controls.AddRange(new Control[] { lblInfo, _txtKey, lblHardware, _lblStatus, _btnActivate, _btnExit }); } private static string FormatInitialStatus(LicenseValidationResult? lastResult) { if (lastResult is null) return ""; // IsTransient means the server gave no verdict at all — telling the user their // license is bad would be wrong, the connection is. if (lastResult.IsTransient) { return "Das Deployment Center ist derzeit nicht erreichbar und es liegt keine " + "gültige Offline-Prüfung mehr vor. Bitte Verbindung prüfen und erneut versuchen.\n" + lastResult.Message; } return $"Letzte Prüfung: {lastResult.Status} — {lastResult.Message}"; } private async Task ActivateAsync() { var key = _txtKey.Text.Trim(); if (string.IsNullOrWhiteSpace(key)) { _lblStatus.ForeColor = Color.Firebrick; _lblStatus.Text = "Bitte einen Lizenzschlüssel eingeben."; return; } _btnActivate.Enabled = false; _lblStatus.ForeColor = Color.DimGray; _lblStatus.Text = "Prüfe Lizenz am Deployment Center..."; try { var result = await _client.ValidateAsync(DcConfig.ProductSlug, key, DcConfig.BaseUrl); if (result.IsValid) { Session = new LicenseSession(_client, key, result); DialogResult = DialogResult.OK; Close(); return; } _lblStatus.ForeColor = Color.Firebrick; _lblStatus.Text = $"Lizenz nicht nutzbar ({result.Status}):\n{result.Message}"; } catch (Exception ex) { _lblStatus.ForeColor = Color.Firebrick; _lblStatus.Text = $"Fehler bei der Prüfung: {ex.Message}"; } finally { _btnActivate.Enabled = true; } } }