Files
quality_recticel/windows_print_service/print_service.ps1

267 lines
9.5 KiB
PowerShell

# Quality Recticel Print Service - PowerShell Implementation
# Native Windows solution with no external dependencies
param(
[int]$Port = 8765,
[string]$LogFile = "$env:ProgramFiles\QualityRecticel\PrintService\print_service.log"
)
# Ensure log directory exists
$logDir = Split-Path $LogFile -Parent
if (!(Test-Path $logDir)) {
New-Item -ItemType Directory -Path $logDir -Force | Out-Null
}
# Logging function
function Write-ServiceLog {
param([string]$Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] $Message"
Write-Host $logMessage
Add-Content -Path $LogFile -Value $logMessage -ErrorAction SilentlyContinue
}
# Get available printers
function Get-AvailablePrinters {
try {
$printers = Get-WmiObject -Class Win32_Printer | Where-Object { $_.Local -eq $true } | ForEach-Object {
@{
name = $_.Name
driver = $_.DriverName
port = $_.PortName
is_default = $_.Default
status = $_.PrinterStatus
}
}
return @{
success = $true
printers = $printers
count = $printers.Count
}
}
catch {
Write-ServiceLog "Error getting printers: $($_.Exception.Message)"
return @{
success = $false
error = $_.Exception.Message
printers = @()
}
}
}
# Print PDF function
function Invoke-PrintPDF {
param(
[string]$PdfUrl,
[string]$PrinterName = "default",
[int]$Copies = 1
)
try {
Write-ServiceLog "Print request: URL=$PdfUrl, Printer=$PrinterName, Copies=$Copies"
# Download PDF to temp file
$tempFile = [System.IO.Path]::GetTempFileName() + ".pdf"
$webClient = New-Object System.Net.WebClient
$webClient.DownloadFile($PdfUrl, $tempFile)
Write-ServiceLog "PDF downloaded to: $tempFile"
# Get default printer if needed
if ($PrinterName -eq "default" -or [string]::IsNullOrEmpty($PrinterName)) {
$defaultPrinter = Get-WmiObject -Class Win32_Printer | Where-Object { $_.Default -eq $true }
$PrinterName = $defaultPrinter.Name
}
# Print using Windows shell
$printJob = Start-Process -FilePath $tempFile -Verb Print -PassThru -WindowStyle Hidden
Start-Sleep -Seconds 2
# Clean up temp file
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
Write-ServiceLog "Print job sent successfully to printer: $PrinterName"
return @{
success = $true
message = "Print job sent successfully"
printer = $PrinterName
timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
}
}
catch {
Write-ServiceLog "Print error: $($_.Exception.Message)"
return @{
success = $false
error = $_.Exception.Message
}
}
}
# HTTP Response function
function Send-HttpResponse {
param(
[System.Net.HttpListenerContext]$Context,
[int]$StatusCode = 200,
[string]$ContentType = "application/json",
[string]$Body = ""
)
try {
$Context.Response.StatusCode = $StatusCode
$Context.Response.ContentType = "$ContentType; charset=utf-8"
# Add CORS headers
$Context.Response.Headers.Add("Access-Control-Allow-Origin", "*")
$Context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
$Context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization")
if ($Body) {
$buffer = [System.Text.Encoding]::UTF8.GetBytes($Body)
$Context.Response.ContentLength64 = $buffer.Length
$Context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
}
$Context.Response.OutputStream.Close()
}
catch {
Write-ServiceLog "Error sending response: $($_.Exception.Message)"
}
}
# Main HTTP server function
function Start-PrintService {
Write-ServiceLog "Starting Quality Recticel Print Service on port $Port"
try {
# Create HTTP listener
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://localhost:$Port/")
$listener.Prefixes.Add("http://127.0.0.1:$Port/")
$listener.Start()
Write-ServiceLog "HTTP server started on http://localhost:$Port"
# Main server loop
while ($listener.IsListening) {
try {
# Wait for request
$context = $listener.GetContext()
$request = $context.Request
$response = $context.Response
$method = $request.HttpMethod
$url = $request.Url.AbsolutePath
Write-ServiceLog "$method $url"
# Handle different endpoints
switch -Regex ($url) {
"^/health$" {
$healthData = @{
status = "healthy"
service = "Quality Recticel Print Service"
version = "1.0"
timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
platform = "Windows PowerShell"
}
Send-HttpResponse -Context $context -Body ($healthData | ConvertTo-Json)
}
"^/printers$" {
$printersData = Get-AvailablePrinters
Send-HttpResponse -Context $context -Body ($printersData | ConvertTo-Json -Depth 3)
}
"^/print/(pdf|silent)$" {
if ($method -eq "POST") {
try {
# Read request body
$reader = New-Object System.IO.StreamReader($request.InputStream)
$body = $reader.ReadToEnd()
$reader.Close()
# Parse JSON
$printData = $body | ConvertFrom-Json
# Print PDF
$result = Invoke-PrintPDF -PdfUrl $printData.pdf_url -PrinterName $printData.printer_name -Copies $printData.copies
if ($result.success) {
Send-HttpResponse -Context $context -Body ($result | ConvertTo-Json)
} else {
Send-HttpResponse -Context $context -StatusCode 500 -Body ($result | ConvertTo-Json)
}
}
catch {
$errorResponse = @{
success = $false
error = "Invalid request: $($_.Exception.Message)"
}
Send-HttpResponse -Context $context -StatusCode 400 -Body ($errorResponse | ConvertTo-Json)
}
} else {
$errorResponse = @{
success = $false
error = "Method not allowed"
}
Send-HttpResponse -Context $context -StatusCode 405 -Body ($errorResponse | ConvertTo-Json)
}
}
"^/options$" {
# Handle CORS preflight
Send-HttpResponse -Context $context -StatusCode 200
}
default {
$errorResponse = @{
success = $false
error = "Endpoint not found"
available_endpoints = @("/health", "/printers", "/print/pdf", "/print/silent")
}
Send-HttpResponse -Context $context -StatusCode 404 -Body ($errorResponse | ConvertTo-Json)
}
}
}
catch {
Write-ServiceLog "Request error: $($_.Exception.Message)"
try {
$errorResponse = @{
success = $false
error = "Internal server error"
}
Send-HttpResponse -Context $context -StatusCode 500 -Body ($errorResponse | ConvertTo-Json)
}
catch {
# Ignore response errors
}
}
}
}
catch {
Write-ServiceLog "Fatal error: $($_.Exception.Message)"
}
finally {
if ($listener) {
$listener.Stop()
$listener.Close()
}
Write-ServiceLog "Print service stopped"
}
}
# Service entry point
Write-ServiceLog "Quality Recticel Print Service starting..."
# Handle service stop gracefully
Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {
Write-ServiceLog "Service shutting down..."
}
# Start the service
try {
Start-PrintService
}
catch {
Write-ServiceLog "Service failed to start: $($_.Exception.Message)"
exit 1
}