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;
}
}
}