Make printer registration manual

This commit is contained in:
2026-05-30 23:58:20 +02:00
parent 26f056684c
commit e3c153fb0f
6 changed files with 100 additions and 29 deletions
+2 -2
View File
@@ -67,9 +67,9 @@ Content-Type: image/png
Body: binäres PNG-Bild.
## 3. Drucker registrieren (Agent-Start)
## 3. Drucker registrieren (Benutzeraktion in den Agent-Einstellungen)
Der Agent ruft diesen Endpunkt beim Start für jeden konfigurierten lokalen Windows-Drucker auf.
Der Agent ruft diesen Endpunkt nicht automatisch beim Start auf. Der Benutzer registriert die freigegebenen lokalen Windows-Drucker bewusst über die Agent-Einstellungen.
```http
POST /api/label-print-agent/printers/register
+2 -2
View File
@@ -148,7 +148,7 @@ Beispiel:
Der API-Token wird lokal mit Windows DPAPI verschlüsselt gespeichert.
Beim Start registriert der Agent jeden Eintrag aus `printers` beim Backend. Das Feld `printer` bleibt als Kompatibilitätsfeld für ältere Einstellungen erhalten; neue Jobs werden anhand von `windowsPrinterName` aus der Backend-Antwort auf den passenden lokalen Windows-Drucker gedruckt.
Der Agent registriert Drucker nicht automatisch. Im Tab `Drucker` kann der Benutzer die freigegebenen Einträge aus `printers` bewusst mit `Im Backend registrieren` an das Backend melden. Das Feld `printer` bleibt als Kompatibilitätsfeld für ältere Einstellungen erhalten; neue Jobs werden anhand von `windowsPrinterName` aus der Backend-Antwort auf den passenden lokalen Windows-Drucker gedruckt.
## Dymo-Druck
@@ -166,7 +166,7 @@ Wichtig:
1. Anwendung starten.
2. Tray-Symbol öffnen.
3. Im Tab `Backend` BaseUrl, AgentId und optional API-Token eintragen.
4. Im Tab `Drucker` den Dymo LabelWriter auswählen.
4. Im Tab `Drucker` die freigegebenen Drucker konfigurieren und mit `Im Backend registrieren` ans Backend melden.
5. Im Tab `Allgemein` Polling aktivieren und Intervall setzen.
6. Mit `Jetzt prüfen` kann sofort ein Poll-Lauf ausgelöst werden; dabei werden alle aktuell verfügbaren Jobs verarbeitet.
+1 -1
View File
@@ -28,7 +28,7 @@ internal static class Program
using var backendWorker = new BackendPollingWorker(settingsStore, backendClient, printerService);
backendWorker.Start();
Application.Run(new TrayApplicationContext(settingsStore, printerService, backendWorker, updateService));
Application.Run(new TrayApplicationContext(settingsStore, printerService, backendClient, backendWorker, updateService));
}
catch (Exception ex)
{
+91 -21
View File
@@ -14,6 +14,7 @@ internal sealed class SettingsForm : Form
private readonly SettingsStore _settingsStore;
private readonly PrinterService _printerService;
private readonly BackendClient _backendClient;
private readonly BackendPollingWorker _backendWorker;
private readonly UpdateService _updateService;
private UpdateCheckResult? _lastUpdateCheck;
@@ -41,6 +42,7 @@ internal sealed class SettingsForm : Form
private readonly Button _installUpdateButton;
private readonly ComboBox _printer = new() { Width = 360, DropDownStyle = ComboBoxStyle.DropDownList };
private readonly CheckedListBox _sharedPrinters = new() { Width = 360, Height = 125, CheckOnClick = true };
private readonly NumericUpDown _labelWidth = new() { Minimum = 1, Maximum = 500, DecimalPlaces = 1, Value = 57, Width = 100 };
private readonly NumericUpDown _labelHeight = new() { Minimum = 1, Maximum = 500, DecimalPlaces = 1, Value = 32, Width = 100 };
@@ -55,11 +57,13 @@ internal sealed class SettingsForm : Form
public SettingsForm(
SettingsStore settingsStore,
PrinterService printerService,
BackendClient backendClient,
BackendPollingWorker backendWorker,
UpdateService updateService)
{
_settingsStore = settingsStore;
_printerService = printerService;
_backendClient = backendClient;
_backendWorker = backendWorker;
_updateService = updateService;
_installUpdateButton = ButtonAt("Update installieren", 340, 265, async (_, _) => await InstallUpdateFromUiAsync());
@@ -116,11 +120,19 @@ internal sealed class SettingsForm : Form
private TabPage CreatePrinterTab()
{
var panel = CreatePaddedPanel();
panel.Controls.Add(Row(20, Label("Drucker", 120), _printer));
panel.Controls.Add(Row(60, Label("Breite", 120), _labelWidth, Label("mm", 40)));
panel.Controls.Add(Row(100, Label("Höhe", 120), _labelHeight, Label("mm", 40)));
panel.Controls.Add(ButtonAt("Drucker neu laden", 140, 150, (_, _) => LoadPrinters()));
panel.Controls.Add(ButtonAt("Speichern", 300, 150, (_, _) => SavePrinter(showMessage: true)));
panel.Controls.Add(Row(20, Label("Standarddrucker", 120), _printer));
var sharedLabel = Label("Freigegeben", 120);
sharedLabel.Left = 20;
sharedLabel.Top = 60;
_sharedPrinters.Left = 145;
_sharedPrinters.Top = 60;
panel.Controls.Add(sharedLabel);
panel.Controls.Add(_sharedPrinters);
panel.Controls.Add(Row(200, Label("Breite", 120), _labelWidth, Label("mm", 40)));
panel.Controls.Add(Row(240, Label("Höhe", 120), _labelHeight, Label("mm", 40)));
panel.Controls.Add(ButtonAt("Drucker neu laden", 140, 295, (_, _) => LoadPrinters()));
panel.Controls.Add(ButtonAt("Speichern", 300, 295, (_, _) => SavePrinter(showMessage: true)));
panel.Controls.Add(ButtonAt("Im Backend registrieren", 430, 295, async (_, _) => await RegisterPrintersFromUiAsync()));
return new TabPage("Drucker") { Controls = { panel } };
}
@@ -181,10 +193,16 @@ internal sealed class SettingsForm : Form
var settings = _settingsStore.Load();
var selected = GetPrimaryPrinter(settings)?.WindowsPrinterName ?? settings.Printer.PrinterName;
_printer.Items.Clear();
_sharedPrinters.Items.Clear();
var sharedPrinterNames = settings.Printers
.Select(printer => printer.WindowsPrinterName)
.Where(name => !string.IsNullOrWhiteSpace(name))
.ToHashSet(StringComparer.OrdinalIgnoreCase);
var printers = _printerService.GetInstalledPrinters();
foreach (var printer in printers)
{
_printer.Items.Add(printer);
_sharedPrinters.Items.Add(printer, sharedPrinterNames.Contains(printer.Name));
}
var configuredPrinter = printers.FirstOrDefault(printer => string.Equals(printer.Name, selected, StringComparison.OrdinalIgnoreCase));
@@ -231,26 +249,17 @@ internal sealed class SettingsForm : Form
{
var settings = _settingsStore.Load();
var selectedPrinterName = GetSelectedPrinterName() ?? string.Empty;
var sharedPrinterNames = GetSharedPrinterNames();
settings.Printer.PrinterName = selectedPrinterName;
settings.Printer.LabelWidthMm = _labelWidth.Value;
settings.Printer.LabelHeightMm = _labelHeight.Value;
if (!string.IsNullOrWhiteSpace(selectedPrinterName))
settings.Printers = sharedPrinterNames
.Select(printerName => BuildPrinterConfig(settings, printerName))
.ToList();
if (settings.Printers.Count == 0 && !string.IsNullOrWhiteSpace(selectedPrinterName))
{
var existingPrinter = settings.Printers.FirstOrDefault(
printer => string.Equals(printer.WindowsPrinterName, selectedPrinterName, StringComparison.OrdinalIgnoreCase));
var printerConfig = existingPrinter ?? new PrinterConfig();
printerConfig.PrinterId = string.IsNullOrWhiteSpace(printerConfig.PrinterId)
? SettingsStore.BuildPrinterId(settings.Backend.AgentId, selectedPrinterName)
: printerConfig.PrinterId;
printerConfig.Name = string.IsNullOrWhiteSpace(printerConfig.Name) ? selectedPrinterName : printerConfig.Name;
printerConfig.WindowsPrinterName = selectedPrinterName;
printerConfig.Dpi = settings.Printer.Dpi;
printerConfig.DefaultWidthMm = Math.Max(1, (int)Math.Round(_labelWidth.Value));
printerConfig.DefaultHeightMm = Math.Max(1, (int)Math.Round(_labelHeight.Value));
if (existingPrinter is null)
{
settings.Printers.Add(printerConfig);
}
settings.Printers.Add(BuildPrinterConfig(settings, selectedPrinterName));
}
_settingsStore.Save(settings);
@@ -292,6 +301,34 @@ internal sealed class SettingsForm : Form
}
}
private async Task RegisterPrintersFromUiAsync()
{
try
{
SaveBackend(showMessage: false);
SavePrinter(showMessage: false);
var settings = _settingsStore.Load();
var printerCount = settings.Printers.Count(printer => !string.IsNullOrWhiteSpace(printer.WindowsPrinterName));
if (printerCount == 0)
{
MessageBox.Show("Bitte zuerst mindestens einen Drucker konfigurieren.", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
AppendStatus($"{printerCount} Drucker werden im Backend registriert...");
await _backendClient.RegisterPrintersAsync();
AppendStatus($"{printerCount} Drucker im Backend registriert.");
MessageBox.Show("Drucker wurden im Backend registriert.", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
Log.Error(ex, "Printer registration failed");
AppendStatus($"Druckerregistrierung fehlgeschlagen: {ex.Message}");
MessageBox.Show($"Druckerregistrierung fehlgeschlagen: {ex.Message}", Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private async Task CheckForUpdateFromUiAsync()
{
try
@@ -379,6 +416,39 @@ internal sealed class SettingsForm : Form
};
}
private List<string> GetSharedPrinterNames()
{
return _sharedPrinters.CheckedItems
.Cast<object>()
.Select(item => item switch
{
PrinterInfo printerInfo => printerInfo.Name,
string printerName => printerName,
_ => null
})
.Where(printerName => !string.IsNullOrWhiteSpace(printerName))
.Cast<string>()
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
}
private PrinterConfig BuildPrinterConfig(AppSettings settings, string printerName)
{
var existingPrinter = settings.Printers.FirstOrDefault(
printer => string.Equals(printer.WindowsPrinterName, printerName, StringComparison.OrdinalIgnoreCase));
return new PrinterConfig
{
PrinterId = string.IsNullOrWhiteSpace(existingPrinter?.PrinterId)
? SettingsStore.BuildPrinterId(settings.Backend.AgentId, printerName)
: existingPrinter.PrinterId,
Name = string.IsNullOrWhiteSpace(existingPrinter?.Name) ? printerName : existingPrinter.Name,
WindowsPrinterName = printerName,
Dpi = existingPrinter?.Dpi > 0 ? existingPrinter.Dpi : settings.Printer.Dpi,
DefaultWidthMm = Math.Max(1, (int)Math.Round(_labelWidth.Value)),
DefaultHeightMm = Math.Max(1, (int)Math.Round(_labelHeight.Value))
};
}
private static PrinterConfig? GetPrimaryPrinter(AppSettings settings)
{
return settings.Printers.FirstOrDefault(printer => !string.IsNullOrWhiteSpace(printer.WindowsPrinterName));
@@ -11,6 +11,7 @@ internal sealed class TrayApplicationContext : ApplicationContext
private readonly NotifyIcon _notifyIcon;
private readonly SettingsStore _settingsStore;
private readonly PrinterService _printerService;
private readonly BackendClient _backendClient;
private readonly BackendPollingWorker _backendWorker;
private readonly UpdateService _updateService;
private readonly Icon _healthyIcon;
@@ -21,11 +22,13 @@ internal sealed class TrayApplicationContext : ApplicationContext
public TrayApplicationContext(
SettingsStore settingsStore,
PrinterService printerService,
BackendClient backendClient,
BackendPollingWorker backendWorker,
UpdateService updateService)
{
_settingsStore = settingsStore;
_printerService = printerService;
_backendClient = backendClient;
_backendWorker = backendWorker;
_updateService = updateService;
_healthyIcon = TrayIconFactory.CreatePrinterIcon(Color.FromArgb(36, 160, 72));
@@ -62,7 +65,7 @@ internal sealed class TrayApplicationContext : ApplicationContext
{
if (_settingsForm is null || _settingsForm.IsDisposed)
{
_settingsForm = new SettingsForm(_settingsStore, _printerService, _backendWorker, _updateService);
_settingsForm = new SettingsForm(_settingsStore, _printerService, _backendClient, _backendWorker, _updateService);
}
_settingsForm.Show();
@@ -64,8 +64,6 @@ public sealed class BackendPollingWorker : IDisposable
return;
}
await _backendClient.RegisterPrintersAsync(cancellationToken);
var unavailablePrinters = configuredPrinters
.Where(printer => !_printerService.IsPrinterAvailable(printer.WindowsPrinterName))
.Select(printer => printer.WindowsPrinterName)