270 lines
9.8 KiB
PowerShell
270 lines
9.8 KiB
PowerShell
# Quality Label Printing Service - PowerShell Implementation
|
|
# Native Windows solution with no external dependencies
|
|
|
|
param(
|
|
[int]$Port = 8765,
|
|
[string]$LogFile = "$env:ProgramFiles\QualityLabelPrinting\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 comprehensive CORS headers
|
|
$Context.Response.Headers.Add("Access-Control-Allow-Origin", "*")
|
|
$Context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE")
|
|
$Context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, Origin, X-Requested-With")
|
|
$Context.Response.Headers.Add("Access-Control-Max-Age", "86400")
|
|
|
|
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 Label Printing 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 CORS preflight requests first
|
|
if ($method -eq "OPTIONS") {
|
|
Write-ServiceLog "Handling CORS preflight request for $url"
|
|
Send-HttpResponse -Context $context -StatusCode 200
|
|
continue
|
|
}
|
|
|
|
# Handle different endpoints
|
|
switch -Regex ($url) {
|
|
"^/health$" {
|
|
$healthData = @{
|
|
status = "healthy"
|
|
service = "Quality Label Printing 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)
|
|
}
|
|
}
|
|
|
|
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 Label Printing 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
|
|
} |