9.8 KiB
Harbor/Clipper Print Service - Implementation Plan
TL;DR: Build a persistent Windows service that monitors for new print capture files, immediately moves them to prevent overwrites, queues them for ordered processing, and sends multi-tray print jobs to laser printers with document-type-specific configurations.
Recommended Approach: C#/.NET 8+ Windows Service with FileSystemWatcher, print queue, and configurable document templates. C# is completely free (.NET SDK), has superior Windows printer APIs, and excellent service infrastructure.
Steps
Phase 1: Service Foundation (Parallel work possible after step 1)
-
Create Windows Service project structure using .NET 8+ Worker Service template
- Use
BackgroundServicebase class for hosting - Configure as Windows Service with
Microsoft.Extensions.Hosting.WindowsServices - Set up dependency injection, logging, and configuration (appsettings.json)
- Use
-
Implement file monitoring system (parallel with step 3)
FileSystemWatcheron Captures folder withCreated,Changed, andRenamedevents- Debounce logic to handle rapid file creation (buffer 100-200ms)
- Immediate file move to processing queue folder with GUID-based naming to prevent collisions
- Include original filename, timestamp, and metadata in queue
-
Design configuration system (parallel with step 2)
- Document type definitions (invoice, order, delivery, etc.)
- Per-document-type settings: printer name, tray sequence, content transformations
- Global settings: queue folder paths, archive settings, retry policies
- JSON schema for easy editing
Phase 2: Command Interface & Queue Management
-
Create CLI command handler (depends on 1)
- Parse
-f <filepath> -t <doctype> -o <ordernumber>arguments - Check if service is running via named pipe or TCP
- If running: send command to service via IPC
- If not running: log error or auto-start service
- Return exit code immediately
- Parse
-
Build print job queue (depends on 1)
- Thread-safe queue with priority/ordering (FIFO by default, configurable)
- Persistent queue state (survive service restart)
- Job metadata: source file, document type, order number, timestamp, retry count
- Status tracking: pending, processing, completed, failed
-
Implement IPC mechanism (depends on 4, 5)
- Named pipe server listening for commands from CLI
- Deserialize command → create job → enqueue
- Return acknowledgment to caller
Phase 3: Printer Integration
-
Implement queue-based printer control (depends on 5)
- Use
System.Drawing.Printing.PrintDocumentwith Windows print queue - Multi-page document with dynamic
PageSettings.PaperSourcefor tray selection - Per-printer tray mapping configuration (map logical tray numbers to physical
PaperSourceindexes) - Fallback handling when tray empty (configurable: fail job, use default tray, alert)
- Optional: Print to PDF for testing/archiving
- Use
-
Build document processor with Graphics rendering (depends on 7)
- Read queued capture file and parse text content
- Apply document-type-specific transformations:
- Line position adjustments using
Graphics.DrawString()coordinates - Text removal/replacement via regex patterns
- Font and formatting configuration per document type
- Future: header/footer injection, graphics overlay, logo placement
- Line position adjustments using
- Render each page with
GraphicsAPI for pixel-perfect control - Generate multi-page
PrintDocumentwith correct tray sequence - Send to Windows print queue
-
Add printer routing logic (depends on 7, 8)
- Map document types to printer(s) and tray sequences
- Support multiple printer profiles per document type
- Configuration:
{ "invoice": { "printer": "LaserJet-1", "trays": [3,4,1,2] } }
Phase 4: Reliability & Operations
-
Implement error handling & retry (depends on 5, 8)
- Printer offline detection → requeue with exponential backoff
- File read errors → log and move to error folder
- Max retry limit → move to dead letter queue
- Detailed logging with correlation IDs
-
Add file lifecycle management (depends on 2)
- Post-processing: delete or move to archive folder (configurable per document type)
- Archive folder structure: organized by date, document type, or both
- Retention policy support (future: auto-cleanup old archives)
-
Create service installer & deployment (depends on all previous)
- MSI installer or PowerShell install script
- Service registration with
sc.exeor WiX toolset - Auto-start configuration
- Uninstall/upgrade support
Phase 5: Testing & Validation
-
System testing (depends on 12)
- Test rapid file creation (simulate Harbor/Clipper speed)
- Verify no overwrites or missing files
- Confirm correct print order
- Test printer offline scenarios
- Validate tray sequences for each document type
-
Integration with Harbor/Clipper (depends on 13)
- Replace current Rust CLI calls with new CLI
- Monitor production for 24-48 hours
- Compare output quality and reliability
- Performance tuning if needed
Relevant Files
To be created:
PrintService/Program.cs— Service host and startup configurationPrintService/Worker.cs— Background service implementing FileSystemWatcher and queue processorPrintService/Models/PrintJob.cs— Job data modelPrintService/Models/DocumentConfig.cs— Document type configuration schemaPrintService/Services/FileMonitorService.cs— File watching and immediate move logicPrintService/Services/PrintQueueService.cs— Queue management and processingPrintService/Services/PrinterService.cs— Queue-based printer control with tray commandsPrintService/Services/DocumentProcessor.cs— Text parsing and Graphics renderingPrintService/Services/IpcService.cs— Named pipe listener for CLI commandsPrintService/appsettings.json— Configuration file for document types, printers, pathsPrintServiceCLI/Program.cs— Command-line tool for sending commands to servicePrintService.sln— Solution file
Existing:
Captures/— Source folder for Harbor/Clipper output files (will be monitored)
Verification
- Unit tests: Queue ordering, configuration parsing, tray sequence generation
- Integration test: Create 50 files in 10 seconds → verify all printed in order with correct trays
- Stress test: 1000+ files → no overwrites, no missing files, proper ordering
- Manual test: Print each document type to each configured printer and verify tray usage
- Production validation: Monitor service for 48 hours, compare output count with Harbor/Clipper expected count
- Error scenario testing: Unplug printer mid-job → verify retry → reconnect → verify job completes
Decisions
Language: C#/.NET 8+
- Rationale: Free, best Windows service/printer APIs, excellent tooling, easier printer control than Rust
- Alternative: Could still use Rust with
windows-rscrate, but printer control is more complex
Architecture: Service with IPC (Named Pipes)
- CLI tool sends commands → service processes asynchronously
- Decouples Harbor/Clipper from processing delays
File handling: Immediate move with GUID renaming
- Critical: Prevents timestamp collision overwrites
- Original metadata preserved in queue state
Queue persistence: JSON file or SQLite
- Survives service restart
- Allows inspection/recovery
Configuration: JSON file (appsettings.json)
- Editable without recompilation
- Per-document-type printer/tray/transformation settings
Printer control: PrintDocument with Windows print queue
- Per-page tray control via
PageSettings.PaperSource - Content rendered using
Graphics.DrawString()for positioning control - Jobs appear in Windows print queue (pausable, survives restarts)
- Can print to PDF for testing
Scope included:
- Windows service with file monitoring
- Command-line interface for Harbor/Clipper integration
- Multi-tray printer control via Windows print queue
- Configurable document routing
- Archive/delete options
- Error handling and retry logic
- Content transformation with Graphics rendering (line positioning, text removal)
Scope excluded (future enhancements):
- GUI management console (use config file + logs for now)
- Advanced document parsing/templating (start with regex transformations)
- Web API or remote monitoring
- Database storage (use file-based queue initially)
- Automatic printer discovery
- Print preview or validation UI
Further Considerations
- Printer-specific tray mapping: Need to identify your laser printer models and test
PaperSourceindexes. Do you know the printer makes/models? - Content transformation complexity: You mentioned looping line items. For Phase 1, suggest simple regex-based transformations. If parsing becomes complex, consider a template engine (Scriban, Handlebars.NET) in Phase 2.
- Testing environment: Do you have a test laser printer or can we print to PDF initially to verify tray selection and content rendering work correctly?
Benefits of Queue-Based Approach
- ✅ Visibility: Jobs appear in Windows print queue UI
- ✅ Resilience: Queue survives service restarts
- ✅ Control: Can pause/cancel jobs through Windows
- ✅ Testing: Print to PDF for verification without paper waste
- ✅ Content Control:
Graphics.DrawString()gives pixel-perfect positioning for your line adjustments - ✅ Debugging: Easier to troubleshoot than raw printer commands