feat: Add Print Service Tray application with configuration and queue management

- Implemented PrintQueueService with job counting and snapshot retrieval.
- Created Form1 as the main entry point for the tray application.
- Developed ConfigurationForm for managing printer configurations and document types.
- Added models for printer configuration, queue status requests, and responses.
- Established ConfigurationService for loading and saving printer configurations.
- Introduced ServiceClient for IPC communication with the print service.
- Built TrayApplicationContext for managing the system tray icon and status updates.
- Added TODO.md for tracking remaining work and future enhancements.
This commit is contained in:
Jason
2026-05-29 10:43:48 -05:00
parent cce9248089
commit a08da0217d
17 changed files with 1541 additions and 4 deletions
+99
View File
@@ -122,6 +122,17 @@ public class IpcService : IDisposable
_logger.LogDebug("Received IPC message: {Message}", message);
}
// Try to determine command type
var commandType = DetermineCommandType(message);
if (commandType == "GetQueueStatus")
{
var status = GetQueueStatus();
await SendQueueStatusResponse(pipeServer, status);
return;
}
// Handle print command
var command = JsonSerializer.Deserialize<PrintCommand>(message);
if (command == null)
{
@@ -163,6 +174,70 @@ public class IpcService : IDisposable
}
}
/// <summary>
/// Determine the type of command from JSON message
/// </summary>
private string? DetermineCommandType(string message)
{
try
{
using var doc = JsonDocument.Parse(message);
if (doc.RootElement.TryGetProperty("Command", out var cmdProp))
{
return cmdProp.GetString();
}
}
catch { }
return null;
}
/// <summary>
/// Get current queue status
/// </summary>
private QueueStatusResponse GetQueueStatus()
{
try
{
var jobs = _queueService.GetAllJobs();
var jobStatuses = jobs.Select(j => new JobStatus
{
Id = j.Id.ToString(),
FileName = j.OriginalFilename,
DocumentType = j.DocumentType,
Status = j.Status.ToString(),
PrinterName = null, // Will be set when processing starts
CurrentPage = null,
TotalPages = null
}).ToList();
return new QueueStatusResponse
{
Success = true,
Jobs = jobStatuses
};
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get queue status");
return new QueueStatusResponse
{
Success = false,
Message = $"Error: {ex.Message}"
};
}
}
/// <summary>
/// Send queue status response
/// </summary>
private async Task SendQueueStatusResponse(NamedPipeServerStream pipeServer, QueueStatusResponse response)
{
var json = JsonSerializer.Serialize(response);
var bytes = Encoding.UTF8.GetBytes(json);
await pipeServer.WriteAsync(bytes, 0, bytes.Length);
await pipeServer.FlushAsync();
}
/// <summary>
/// Process a print command
/// </summary>
@@ -239,3 +314,27 @@ public class PrintResponse
public bool Success { get; set; }
public string Message { get; set; } = string.Empty;
}
/// <summary>
/// Queue status response for tray app
/// </summary>
public class QueueStatusResponse
{
public bool Success { get; set; }
public string? Message { get; set; }
public List<JobStatus> Jobs { get; set; } = new();
}
/// <summary>
/// Status of a single job
/// </summary>
public class JobStatus
{
public string Id { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
public string DocumentType { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string? PrinterName { get; set; }
public int? CurrentPage { get; set; }
public int? TotalPages { get; set; }
}