Files
TekH 665266457f Migrate legacy VB.NET service to modern C# Worker
Migrated the legacy VB.NET Windows Service to a modern C# Worker Service targeting .NET Framework 4.6.2. Key changes include:

- Added `Microsoft.Extensions.Hosting.WindowsServices`, `NLog`, and `Quartz` for logging and scheduling.
- Introduced `LogConfigFactory` to bridge `ServiceConfig` and `LogConfig` for Quartz jobs.
- Rewrote `Worker` to handle the full service lifecycle, including database connection, temp file management, and scheduler initialization.
- Implemented `SchedulerFinishEnvelope` and `SchedulerEnvelopeTaskApi` for Quartz job scheduling.
- Created `TempFiles` for service-level temp file management.
- Configured `NLog` for file and console logging.
- Updated `appsettings.json` for connection strings and service-specific configuration.
- Replaced legacy `ProjectInstaller` with `AddWindowsService()` for SCM integration.
2026-08-27 11:39:49 +02:00

112 lines
4.1 KiB
C#
Raw Permalink Blame History

using DigitalData.Modules.Database;
using EnvelopeGenerator.Service.Schedulers;
using Microsoft.Extensions.Options;
namespace EnvelopeGenerator.Service;
public sealed class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly ServiceConfig _config;
private readonly string _connectionString;
private readonly TempFiles _tempFiles;
private readonly SchedulerFinishEnvelope _schedulerFinishEnvelope;
private readonly SchedulerEnvelopeTaskApi _schedulerEnvelopeTaskApi;
public Worker(
ILogger<Worker> logger,
IOptions<ServiceConfig> config,
IConfiguration configuration,
TempFiles tempFiles,
SchedulerFinishEnvelope schedulerFinishEnvelope,
SchedulerEnvelopeTaskApi schedulerEnvelopeTaskApi)
{
_logger = logger;
_config = config.Value;
_connectionString = configuration.GetConnectionString("Default")
?? throw new InvalidOperationException("ConnectionStrings:Default is not configured.");
_tempFiles = tempFiles;
_schedulerFinishEnvelope = schedulerFinishEnvelope;
_schedulerEnvelopeTaskApi = schedulerEnvelopeTaskApi;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
_logger.LogInformation("EnvelopeGenerator.Service starting...");
// 1. Validate connection string
if (string.IsNullOrWhiteSpace(_connectionString))
throw new InvalidOperationException("Connection string is empty!");
// 2. Build LogConfig (required by CommonServices jobs via JobDataMap)
var logConfig = LogConfigFactory.Create(_config);
_logger.LogInformation("DEBUG = {Debug}", _config.Debug);
// 3. Connect to DB and load GDPicture license
_logger.LogDebug("Initializing Database...");
var database = new MSSQLServer(logConfig, _connectionString);
if (!database.DBInitialized)
throw new InvalidOperationException("Database connection could not be established!");
_logger.LogDebug("Database initialized.");
var licenseKey = database.GetScalarValue(
"SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE' AND ACTIVE = 1") as string;
if (string.IsNullOrWhiteSpace(licenseKey))
throw new InvalidOperationException("GDPicture license could not be loaded!");
_logger.LogDebug("GDPicture license loaded.");
// 4. Create service-level temp directory
_tempFiles.Create();
// 5. Start FinalizeDocument scheduler
_logger.LogDebug("Initializing schedulers...");
await _schedulerFinishEnvelope.Start(licenseKey!, logConfig);
// 6. Delay between schedulers (legacy behavior preserved)
await Task.Delay(2500, stoppingToken);
// 7. Start API envelope scheduler
await _schedulerEnvelopeTaskApi.Start(logConfig);
_logger.LogInformation("EnvelopeGenerator.Service started!");
// 8. Wait for cancellation (service runs until stopped)
await Task.Delay(Timeout.Infinite, stoppingToken);
}
catch (OperationCanceledException)
{
// Normal shutdown <20> not an error
}
catch (Exception ex)
{
_logger.LogError(ex, "EnvelopeGenerator.Service encountered a fatal error during startup.");
throw;
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("EnvelopeGenerator.Service stopping...");
try
{
await _schedulerFinishEnvelope.Stop();
await _schedulerEnvelopeTaskApi.Stop();
_tempFiles.CleanUp();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error during service shutdown.");
}
await base.StopAsync(cancellationToken);
_logger.LogInformation("EnvelopeGenerator.Service stopped!");
}
}