updated : solutions

This commit is contained in:
2025-09-26 22:51:16 +03:00
parent 1f90602550
commit 5765798905
53 changed files with 256 additions and 7746 deletions

View File

@@ -1,74 +0,0 @@
# Windows Print Service Network Configuration Guide
## Current Issue
Your Flask server (Linux) cannot connect to Windows Print Service because they're on different machines.
## Solution Options
### Option 1: Same Machine Setup
If both Flask and Windows service are on the same machine:
```python
WINDOWS_PRINT_SERVICE_URL = "http://localhost:8765"
```
### Option 2: Different Machines (Recommended)
If Flask server (Linux) and Windows service are on different machines:
1. **Find Windows Machine IP Address:**
```cmd
# On Windows machine, run:
ipconfig
# Look for IPv4 Address, e.g., 192.168.1.100
```
2. **Update Configuration:**
```python
# In /app/print_config.py, change:
WINDOWS_PRINT_SERVICE_URL = "http://192.168.1.100:8765"
```
3. **Test Connection:**
```bash
# From Linux machine, test:
curl http://192.168.1.100:8765/health
```
### Option 3: Windows Firewall Configuration
Ensure Windows allows incoming connections on port 8765:
1. **Windows Firewall Settings:**
- Control Panel → System and Security → Windows Defender Firewall
- Advanced Settings → Inbound Rules → New Rule
- Port → TCP → 8765 → Allow the connection
2. **Test from Linux:**
```bash
telnet [WINDOWS_IP] 8765
```
### Option 4: Port Forwarding/Tunneling
If direct connection isn't possible, set up SSH tunnel or port forwarding.
## Quick Fix for Testing
1. **Get Windows IP Address**
2. **Update print_config.py with the IP**
3. **Restart Flask server**
4. **Test printing**
## Current Status
- ✅ Windows Print Service: Running (localhost:8765/health works)
- ❌ Network Connection: Flask can't reach Windows service
- 🔧 Fix Needed: Update WINDOWS_PRINT_SERVICE_URL with correct IP
## Example Commands
```bash
# 1. Find Windows IP (run on Windows):
# ipconfig | findstr IPv4
# 2. Test connection (run on Linux):
# curl http://[WINDOWS_IP]:8765/health
# 3. Update config and restart Flask
```

View File

@@ -1,125 +0,0 @@
#!/usr/bin/env python3
"""
PDF Label Dimension Analysis Tool
Analyzes the generated PDF to verify exact dimensions and content positioning
"""
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'app'))
from app.pdf_generator import LabelPDFGenerator, mm_to_points
from reportlab.lib.units import mm
def analyze_pdf_dimensions():
"""Analyze the PDF dimensions in detail"""
print("=== PDF Label Dimension Analysis ===\n")
generator = LabelPDFGenerator()
# Label dimensions
print("1. LABEL PHYSICAL DIMENSIONS:")
print(f" Width: {generator.label_width/mm:.1f}mm ({generator.label_width:.2f} points)")
print(f" Height: {generator.label_height/mm:.1f}mm ({generator.label_height:.2f} points)")
print(f" ✓ Should be exactly 80.0mm × 110.0mm")
# Content area
print(f"\n2. CONTENT AREA DIMENSIONS:")
print(f" Content Width: {generator.content_width/mm:.1f}mm")
print(f" Content Height: {generator.content_height/mm:.1f}mm")
print(f" Left margin: {generator.content_x/mm:.1f}mm")
print(f" Bottom margin: {generator.content_y/mm:.1f}mm")
print(f" Right margin: {(generator.label_width - generator.content_x - generator.content_width)/mm:.1f}mm")
print(f" Top margin: {(generator.label_height - generator.content_y - generator.content_height)/mm:.1f}mm")
# Row analysis
print(f"\n3. ROW LAYOUT:")
total_rows = 9
standard_rows = 8 # 7 standard + 1 double
double_rows = 1
standard_row_height_mm = generator.row_height/mm
double_row_height_mm = generator.double_row_height/mm
total_content_used = (standard_rows * standard_row_height_mm + double_rows * double_row_height_mm)
expected_content_height = generator.content_height/mm
print(f" Standard row height: {standard_row_height_mm:.1f}mm")
print(f" Double row height: {double_row_height_mm:.1f}mm")
print(f" Total rows: {total_rows} (8 standard + 1 double)")
print(f" Content height used: {total_content_used:.1f}mm")
print(f" Content area available: {expected_content_height:.1f}mm")
print(f" Remaining space: {expected_content_height - total_content_used:.1f}mm")
# Barcode area
print(f"\n4. BARCODE AREA:")
barcode_bottom_margin = generator.content_y/mm
print(f" Bottom barcode space: {barcode_bottom_margin:.1f}mm (should be ~12-15mm)")
top_margin = (generator.label_height - generator.content_y - generator.content_height)/mm
print(f" Top margin space: {top_margin:.1f}mm")
# Check for potential issues
print(f"\n5. POTENTIAL ISSUES ANALYSIS:")
# Check if content is too high
if total_content_used > expected_content_height:
print(f" ⚠️ ISSUE: Content ({total_content_used:.1f}mm) exceeds available space ({expected_content_height:.1f}mm)")
else:
print(f" ✓ Content fits within available space")
# Check margins
if barcode_bottom_margin < 10:
print(f" ⚠️ WARNING: Bottom margin ({barcode_bottom_margin:.1f}mm) may be too small for barcode")
else:
print(f" ✓ Bottom margin adequate for barcode")
if top_margin < 3:
print(f" ⚠️ WARNING: Top margin ({top_margin:.1f}mm) very small")
else:
print(f" ✓ Top margin adequate")
# Aspect ratio check
aspect_ratio = generator.label_height / generator.label_width
expected_ratio = 110.0 / 80.0 # 1.375
print(f"\n6. ASPECT RATIO CHECK:")
print(f" Current ratio: {aspect_ratio:.3f}")
print(f" Expected ratio: {expected_ratio:.3f} (110/80)")
if abs(aspect_ratio - expected_ratio) < 0.001:
print(f" ✓ Aspect ratio is correct")
else:
print(f" ⚠️ Aspect ratio mismatch!")
# Browser display notes
print(f"\n7. BROWSER DISPLAY CONSIDERATIONS:")
print(f" • Browser zoom affects apparent size")
print(f" • PDF viewer scaling can change appearance")
print(f" • Monitor DPI affects screen dimensions")
print(f" • Print preview scaling may alter appearance")
print(f"\n 🔧 SOLUTION: Always verify with physical printout at 100% scale")
return {
'width_mm': generator.label_width/mm,
'height_mm': generator.label_height/mm,
'content_height_mm': expected_content_height,
'content_used_mm': total_content_used,
'aspect_ratio': aspect_ratio,
'expected_ratio': expected_ratio
}
if __name__ == "__main__":
results = analyze_pdf_dimensions()
print(f"\n=== SUMMARY ===")
if (abs(results['width_mm'] - 80.0) < 0.1 and
abs(results['height_mm'] - 110.0) < 0.1 and
abs(results['aspect_ratio'] - results['expected_ratio']) < 0.001):
print("✅ PDF dimensions are CORRECT: 80mm × 110mm")
print("If labels appear too large, check:")
print(" • Browser zoom level (should be 100%)")
print(" • PDF viewer scaling settings")
print(" • Print scaling (should be 'Actual size' or 100%)")
else:
print("❌ PDF dimensions need adjustment")

View File

@@ -2065,6 +2065,47 @@ def update_printed_status(order_id):
print(f"DEBUG: Error in update_printed_status: {e}")
return jsonify({'error': 'Internal server error'}), 500
@bp.route('/download_print_service')
def download_print_service():
"""Download the direct print service package"""
try:
from flask import send_from_directory, current_app
import os
# Check if complete package is requested
package_type = request.args.get('package', 'basic')
if package_type == 'complete':
# Serve the complete package
filename = 'QualityPrintService_Complete.zip'
else:
# Serve the basic package (legacy)
filename = 'RecticelPrintService.zip'
# Path to the print service files
service_path = os.path.join(current_app.root_path, 'static', 'downloads')
# Create the directory if it doesn't exist
os.makedirs(service_path, exist_ok=True)
# Check if the zip file exists
full_path = os.path.join(service_path, filename)
if not os.path.exists(full_path):
# If the zip doesn't exist, return information about creating it
return jsonify({
'error': f'Print service package ({filename}) not found',
'message': f'The {package_type} print service package is not available',
'suggestion': 'Please contact the administrator or use the basic package'
}), 404
return send_from_directory(service_path, filename, as_attachment=True)
except Exception as e:
print(f"DEBUG: Error downloading print service: {e}")
return jsonify({'error': 'Failed to download print service'}), 500
@bp.route('/get_order_data/<int:order_id>', methods=['GET'])
def get_order_data(order_id):
"""Get specific order data for preview"""

View File

@@ -204,6 +204,25 @@
<div style="margin-bottom: 5px;">Creates sequential labels based on quantity</div>
<small>(e.g., CP00000711-001 to CP00000711-063)</small>
</div>
<!-- Direct Print Service Download -->
<div style="width: 100%; text-align: center; margin-top: 20px; padding-top: 15px; border-top: 1px solid #e9ecef;">
<div style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; padding: 12px; margin-bottom: 10px;">
<div style="font-size: 11px; color: #856404; margin-bottom: 8px;">
<strong>📦 Quality Print Service</strong>
</div>
<div style="font-size: 10px; color: #6c757d; margin-bottom: 10px; line-height: 1.3;">
Professional Windows service for instant direct printing to thermal label printers without PDF dialogs
</div>
<a href="{{ url_for('main.download_print_service') }}?package=complete" class="btn btn-outline-warning btn-sm" download style="font-size: 10px; padding: 4px 12px; text-decoration: none;">
📥 Download Complete Package
</a>
</div>
<div style="font-size: 9px; color: #6c757d; margin-top: 5px; line-height: 1.2;">
<strong>Easy Install:</strong> Extract → Run install.bat as Admin → Done!<br>
<small>Supports all thermal printers • Auto-starts with Windows • One-click installation</small>
</div>
</div>
</div>
</div> <!-- Data Preview Card -->
<div class="card scan-table-card" style="min-height: 700px; width: calc(100% - 350px); margin: 0;">
@@ -330,6 +349,9 @@ document.getElementById('check-db-btn').addEventListener('click', function() {
// Initialize PDF generation functionality
addPDFGenerationHandler();
// Initialize print service
initializePrintService();
// Auto-select first row
setTimeout(() => {
const firstRow = document.querySelector('.print-module-table tbody tr');
@@ -396,6 +418,96 @@ function updateLabelPreview(order) {
document.getElementById('barcode-text').textContent = prodOrder;
}
// Initialize print service connection and load available printers
function initializePrintService() {
// Check service status and load printers
checkPrintServiceStatus()
.then(serviceStatus => {
if (serviceStatus) {
console.log('✅ Print service is available');
loadAvailablePrinters();
updateServiceStatusIndicator(true);
} else {
console.log('⚠️ Print service not available');
updateServiceStatusIndicator(false);
}
})
.catch(error => {
console.log('❌ Print service connection failed:', error);
updateServiceStatusIndicator(false);
});
}
// Load available printers from print service
function loadAvailablePrinters() {
fetch('http://localhost:8899/printers', {
method: 'GET',
mode: 'cors'
})
.then(response => response.json())
.then(data => {
const printerSelect = document.getElementById('printerSelect');
// Clear existing options except default ones
const defaultOptions = ['default', 'Epson TM-T20', 'Citizen CTS-310', 'custom'];
Array.from(printerSelect.options).forEach(option => {
if (!defaultOptions.includes(option.value)) {
option.remove();
}
});
// Add available printers
if (data.printers && data.printers.length > 0) {
data.printers.forEach(printer => {
// Don't add if already exists in default options
if (!defaultOptions.includes(printer.name)) {
const option = document.createElement('option');
option.value = printer.name;
option.textContent = `${printer.name}${printer.default ? ' (Default)' : ''}${printer.status !== 'ready' ? ' - Offline' : ''}`;
// Insert before "Other Printer..." option
const customOption = printerSelect.querySelector('option[value="custom"]');
printerSelect.insertBefore(option, customOption);
}
});
// Set default printer if available
const defaultPrinter = data.printers.find(p => p.default);
if (defaultPrinter) {
printerSelect.value = defaultPrinter.name;
}
}
console.log(`Loaded ${data.printers.length} printers from service`);
})
.catch(error => {
console.log('Could not load printers from service:', error);
});
}
// Update service status indicator
function updateServiceStatusIndicator(isAvailable) {
// Find or create status indicator
let statusIndicator = document.getElementById('service-status-indicator');
if (!statusIndicator) {
statusIndicator = document.createElement('div');
statusIndicator.id = 'service-status-indicator';
statusIndicator.style.cssText = 'font-size: 9px; color: #6c757d; margin-top: 5px; text-align: center;';
// Insert after printer selection
const printerSelection = document.getElementById('printerSelection');
printerSelection.appendChild(statusIndicator);
}
if (isAvailable) {
statusIndicator.innerHTML = '🟢 <strong>Print service connected</strong><br><small>Direct printing available</small>';
statusIndicator.style.color = '#28a745';
} else {
statusIndicator.innerHTML = '🔴 <strong>Print service offline</strong><br><small>Install and start the service for direct printing</small>';
statusIndicator.style.color = '#dc3545';
}
}
// PDF Generation System - No printer setup needed
// Labels are generated as PDF files for universal compatibility
function addPDFGenerationHandler() {
@@ -463,67 +575,114 @@ function handleDirectPrint(selectedRow) {
printerName = prompt('Enter your printer name:');
if (!printerName) return;
} else if (printerName === 'default') {
printerName = 'default';
printerName = ''; // Empty for default printer
}
console.log(`Direct printing to: ${printerName}`);
console.log(`Direct printing to: ${printerName || 'default printer'}`);
// Extract order data from selected row
const cells = selectedRow.querySelectorAll('td');
const orderData = {
order_id: parseInt(orderId),
comanda_productie: cells[1].textContent.trim(),
cod_articol: cells[2].textContent.trim(),
descr_com_prod: cells[3].textContent.trim(),
cantitate: parseInt(cells[4].textContent.trim()),
data_livrare: cells[5].textContent.trim(),
dimensiune: cells[6].textContent.trim(),
com_achiz_client: cells[7].textContent.trim(),
nr_linie_com_client: cells[8].textContent.trim(),
customer_name: cells[9].textContent.trim(),
customer_article_number: cells[10].textContent.trim()
};
// Print each label individually
for (let i = 1; i <= quantity; i++) {
const labelData = {
...orderData,
sequential_number: `${orderData.comanda_productie}-${i.toString().padStart(3, '0')}`,
current_label: i,
total_labels: quantity
};
// Encode data as base64 JSON
const jsonString = JSON.stringify(labelData);
const base64Data = btoa(unescape(encodeURIComponent(jsonString)));
// Create custom protocol URL
const printUrl = `recticel-print://${encodeURIComponent(printerName)}/${base64Data}`;
console.log(`Printing label ${i}/${quantity}: ${printUrl.substring(0, 100)}...`);
// Trigger direct print via custom protocol
try {
window.location.href = printUrl;
} catch (error) {
console.error(`Failed to print label ${i}:`, error);
alert(`❌ Failed to print label ${i}/${quantity}. Please check if the print service is installed.`);
return;
// Check if print service is available
checkPrintServiceStatus()
.then(serviceStatus => {
if (!serviceStatus) {
throw new Error('Print service is not available');
}
// Generate PDF first for printing
return generatePrintablePDF(orderId, true); // true for paper-saving mode
})
.then(pdfUrl => {
// Send PDF to print service
const printData = {
pdf_url: pdfUrl,
printer: printerName,
copies: 1,
order_id: parseInt(orderId),
paper_saving: true
};
return fetch('http://localhost:8899/print-pdf', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(printData)
});
})
.then(response => {
if (!response.ok) {
throw new Error(`Print service error: ${response.status}`);
}
return response.json();
})
.then(result => {
if (result.success) {
alert(`✅ Successfully sent ${quantity} labels to printer!\n📊 Order: ${prodOrder}\n🖨️ Printer: ${printerName || 'Default'}\n📄 Job ID: ${result.job_id || 'N/A'}`);
// Update database status and refresh table
updatePrintedStatus(orderId);
} else {
throw new Error(result.error || 'Unknown print error');
}
})
.catch(error => {
console.error('Direct print error:', error);
let errorMessage = '❌ Direct printing failed: ' + error.message;
if (error.message.includes('service is not available')) {
errorMessage += '\n\n💡 Solutions:\n' +
'1. Install the print service using the download link below\n' +
'2. Ensure the service is running (check Windows Services)\n' +
'3. Try restarting the print service\n' +
'4. Use PDF generation as alternative';
} else if (error.message.includes('fetch')) {
errorMessage += '\n\n💡 The print service may not be running.\n' +
'Please start the Quality Print Service from Windows Services.';
}
alert(errorMessage);
});
}
// Helper function to check print service status
function checkPrintServiceStatus() {
return fetch('http://localhost:8899/status', {
method: 'GET',
mode: 'cors'
})
.then(response => {
if (response.ok) {
return response.json().then(data => {
console.log('Print service status:', data);
return data.status === 'running';
});
}
// Small delay between labels to prevent overwhelming the printer
if (i < quantity) {
setTimeout(() => {}, 100);
return false;
})
.catch(error => {
console.log('Print service not available:', error.message);
return false;
});
}
// Helper function to generate PDF for printing
function generatePrintablePDF(orderId, paperSaving = true) {
return fetch(`/generate_labels_pdf/${orderId}/${paperSaving ? 'true' : 'false'}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
}
// Show success message
setTimeout(() => {
alert(`✅ Sent ${quantity} labels to printer: ${printerName}\n📊 Order: ${prodOrder}`);
// Update database status and refresh table
updatePrintedStatus(orderId);
}, 500);
})
.then(response => {
if (!response.ok) {
throw new Error(`Failed to generate PDF: ${response.status}`);
}
return response.blob();
})
.then(blob => {
// Create a temporary URL for the PDF
return URL.createObjectURL(blob);
});
}
function handlePDFGeneration(selectedRow) {

View File

@@ -1,422 +0,0 @@
# Quality Control Management System - Documentation
## Table of Contents
1. [Login System](#login-system)
2. [Dashboard System](#dashboard-system)
3. [User Authentication](#user-authentication)
4. [Role-Based Access Control](#role-based-access-control)
---
## Login System
### Overview
The Quality Control Management System features a dual-database authentication system that provides flexible user management and robust access control. The login system supports both internal SQLite database users and external MariaDB database users.
### Authentication Flow
#### 1. Login Page Access
- **URL**: `/login`
- **Template**: `login.html`
- **Methods**: `GET`, `POST`
#### 2. User Interface
The login page features:
- **Company Logo**: Displayed prominently on the left side
- **Login Form**: Clean, centered form on the right side
- **Required Fields**:
- Username (text input)
- Password (password input)
- **Responsive Design**: Adapts to different screen sizes
#### 3. Authentication Methods
##### Internal Database Authentication
Users can access the system using the internal SQLite database by prefixing their username with `#`:
**Format**: `#username`
**Example**: `#admin` for internal admin user
**Database Details**:
- **Location**: `py_app/instance/users.db`
- **Table**: `users`
- **Schema**: `username, password, role`
- **Use Case**: System administrators, fallback authentication
##### External Database Authentication
Standard authentication uses the external MariaDB database:
**Format**: `username` (no prefix)
**Example**: `john.doe` for external user
**Database Details**:
- **Type**: MariaDB
- **Configuration**: Loaded from `external_database_settings`
- **Table**: `users`
- **Schema**: `username, password, role`
- **Use Case**: Regular operational users
#### 4. Authentication Logic
```python
# Authentication Process Flow
if username.startswith('#'):
# Internal SQLite Database Authentication
username_clean = username[1:].strip()
# Query: py_app/instance/users.db
else:
# External MariaDB Database Authentication
# Primary: External database query
# Fallback: Internal database if external fails
```
#### 5. Security Features
##### Input Validation
- **Required Fields**: Both username and password must be provided
- **Sanitization**: Automatic trimming of whitespace
- **Error Handling**: Clear error messages for invalid inputs
##### Database Connection Security
- **Dual Fallback**: External database with internal fallback
- **Error Isolation**: Database errors don't expose system details
- **Connection Management**: Proper connection opening/closing
##### Session Management
- **Secure Sessions**: User credentials stored in Flask session
- **Role Tracking**: User role preserved for authorization
- **Session Data**:
- `session['user']`: Username
- `session['role']`: User role
#### 6. User Roles
The system supports multiple user roles with different access levels:
- **superadmin**: Full system access, all modules and administrative functions
- **admin**: Administrative access with some limitations
- **quality**: Quality control module access
- **warehouse**: Warehouse management module access
- **scan**: Scanning operations access
- **etichete**: Label management access
- **management**: Management reporting and oversight
#### 7. Login Process
1. **User Navigation**: User accesses `/login` URL
2. **Form Display**: Login form rendered with company branding
3. **Credential Submission**: User enters username/password and submits
4. **Authentication Check**:
- Internal users: Check SQLite database
- External users: Check MariaDB database with SQLite fallback
5. **Session Creation**: Valid credentials create user session
6. **Redirect**: Successful login redirects to `/dashboard`
7. **Error Handling**: Invalid credentials display error message
#### 8. Error Messages
- **Missing Credentials**: "Please enter both username and password."
- **Invalid Credentials**: "Invalid credentials. Please try again."
- **Database Errors**: Handled gracefully with fallback mechanisms
#### 9. Post-Login Behavior
After successful authentication:
- **Session Establishment**: User session created with username and role
- **Dashboard Redirect**: User redirected to main dashboard
- **Access Control**: Role-based permissions applied throughout system
- **Navigation**: Header displays logged-in user information
#### 10. Security Considerations
##### Password Security
- **Storage**: Passwords stored in plaintext (consider encryption upgrade)
- **Transmission**: Form-based submission over HTTPS recommended
- **Session**: Password not stored in session, only username/role
##### Database Security
- **Connection Strings**: External database settings in separate config
- **Error Handling**: Database errors logged but not exposed to users
- **Fallback System**: Ensures availability even if external database fails
### Technical Implementation
#### Frontend Components
- **Template**: `templates/login.html`
- **Styling**: Login-specific CSS in `static/style.css`
- **Assets**: Company logo (`static/logo_login.jpg`)
#### Backend Components
- **Route Handler**: `@bp.route('/login', methods=['GET', 'POST'])`
- **Database Connections**: SQLite and MariaDB integration
- **Session Management**: Flask session handling
- **Error Handling**: Comprehensive exception management
#### Configuration Files
- **External Database**: Configuration loaded from `external_database_settings`
- **Internal Database**: SQLite database in `instance/users.db`
### Usage Examples
#### Standard User Login
```
Username: john.doe
Password: userpassword
Result: Queries external MariaDB database
```
#### Internal Admin Login
```
Username: #admin
Password: adminpassword
Result: Queries internal SQLite database
```
#### System Administrator Login
```
Username: #superadmin
Password: superpass
Result: Internal database, full system access
```
---
## Dashboard System
### Overview
The dashboard serves as the central hub of the Quality Control Management System, providing authenticated users with access to various system modules based on their assigned roles. It features a clean, card-based interface that displays available modules and ensures proper access control.
### Dashboard Access
#### 1. Dashboard Page Access
- **URL**: `/dashboard`
- **Template**: `dashboard.html`
- **Methods**: `GET`
- **Authentication Required**: Yes (redirects to login if not authenticated)
#### 2. User Interface Design
The dashboard features a modern, responsive card-based layout:
- **Container**: Full-width responsive grid layout
- **Module Cards**: Individual cards for each system module
- **Visual Hierarchy**: Clear headings, descriptions, and call-to-action buttons
- **Responsive Design**: Adapts to different screen sizes and devices
#### 3. Available Modules
##### Scanning Module
- **Card Title**: "Access Scanning Module"
- **Description**: "Final scanning module for production orders"
- **Button**: "Launch Scanning Module"
- **Route**: `/scan`
- **Required Roles**: `superadmin`, `scan`
- **Purpose**: Quality control scanning operations for production orders
##### Reports Module (Quality)
- **Card Title**: "Access Reports Module"
- **Description**: "Module for verification and quality settings configuration"
- **Button**: "Launch Reports Module"
- **Route**: `/quality`
- **Required Roles**: `superadmin`, `quality`
- **Purpose**: Quality reporting, defects analysis, and quality control reports
##### Warehouse Module
- **Card Title**: "Access Warehouse Module"
- **Description**: "Access warehouse module functionalities"
- **Button**: "Open Warehouse"
- **Route**: `/warehouse`
- **Required Roles**: `superadmin`, `warehouse`
- **Purpose**: Warehouse management operations and inventory control
##### Labels Module
- **Card Title**: "Access Labels Module"
- **Description**: "Module for label management"
- **Button**: "Launch Labels Module"
- **Route**: `/etichete`
- **Required Roles**: `superadmin`, `etichete`
- **Purpose**: Label creation, template management, and printing operations
##### Settings Module
- **Card Title**: "Manage Settings"
- **Description**: "Access and manage application settings"
- **Button**: "Access Settings Page"
- **Route**: `/settings`
- **Required Roles**: `superadmin` only
- **Purpose**: System configuration, user management, and administrative settings
#### 4. Access Control Logic
The dashboard implements role-based access control at both the display and route levels:
##### Frontend Display Control
All module cards are displayed to all authenticated users, but access is controlled at the route level.
##### Backend Route Protection
Each module route implements permission checking:
```python
# Quality Module Access Control
@bp.route('/quality')
def quality():
if 'role' not in session or session['role'] not in ['superadmin', 'quality']:
flash('Access denied: Quality users only.')
return redirect(url_for('main.dashboard'))
# Warehouse Module Access Control
@bp.route('/warehouse')
def warehouse():
if 'role' not in session or session['role'] not in ['superadmin', 'warehouse']:
flash('Access denied: Warehouse users only.')
return redirect(url_for('main.dashboard'))
# Scanning Module Access Control
@bp.route('/scan')
def scan():
if 'role' not in session or session['role'] not in ['superadmin', 'scan']:
flash('Access denied: Scan users only.')
return redirect(url_for('main.dashboard'))
# Labels Module Access Control
@bp.route('/etichete')
def etichete():
if 'role' not in session or session['role'] not in ['superadmin', 'etichete']:
flash('Access denied: Etichete users only.')
return redirect(url_for('main.dashboard'))
# Settings Module Access Control (Superadmin Only)
def settings_handler():
if 'role' not in session or session['role'] != 'superadmin':
flash('Access denied: Superadmin only.')
return redirect(url_for('main.dashboard'))
```
#### 5. User Experience Flow
1. **Authentication Check**: User must be logged in to access dashboard
2. **Dashboard Display**: All module cards shown regardless of role
3. **Module Selection**: User clicks on desired module button
4. **Permission Validation**: System checks user role against module requirements
5. **Access Grant/Deny**:
- **Authorized**: User redirected to module interface
- **Unauthorized**: Error message displayed, user remains on dashboard
#### 6. Session Management
The dashboard relies on Flask session management:
- **Session Check**: `if 'user' not in session` validates authentication
- **Role Access**: `session['role']` determines module permissions
- **Debug Logging**: Session information logged for troubleshooting
#### 7. Error Handling
##### Authentication Errors
- **Unauthenticated Users**: Automatic redirect to login page
- **Session Timeout**: Redirect to login with appropriate messaging
##### Authorization Errors
- **Insufficient Permissions**: Flash message with specific role requirements
- **Access Denied**: User returned to dashboard with error notification
- **Clear Messaging**: Specific error messages indicate required permissions
#### 8. Security Features
##### Session Security
- **Authentication Required**: All dashboard access requires valid session
- **Role Validation**: Each module validates user role before access
- **Automatic Redirect**: Unauthorized access redirected safely
##### Access Control
- **Principle of Least Privilege**: Users only access modules for their role
- **Superadmin Override**: Superadmin role has access to all modules
- **Route-Level Protection**: Backend validation prevents unauthorized access
#### 9. Module Descriptions
##### Quality Reports Module
- **Primary Function**: Generate quality control reports and analytics
- **Key Features**:
- Daily, weekly, and custom date range reports
- Quality defects analysis and tracking
- Export capabilities (CSV format)
- Database testing tools (superadmin only)
##### Scanning Module
- **Primary Function**: Production order scanning and quality validation
- **Key Features**:
- Barcode/QR code scanning interface
- Real-time quality validation
- Production order processing
##### Warehouse Module
- **Primary Function**: Warehouse operations and inventory management
- **Key Features**:
- Inventory tracking and management
- Location management
- Warehouse reporting
##### Labels Module
- **Primary Function**: Label design, generation, and printing
- **Key Features**:
- Label template creation and management
- Dynamic label generation
- Print management system
##### Settings Module
- **Primary Function**: System administration and configuration
- **Key Features**:
- User account management
- Role and permission configuration
- Database settings management
- System configuration options
#### 10. Technical Implementation
##### Frontend Components
- **Template**: `templates/dashboard.html`
- **Styling**: Dashboard-specific CSS classes in `static/style.css`
- **Layout**: CSS Grid/Flexbox responsive card layout
- **Navigation**: Base template integration with header/footer
##### Backend Components
- **Route Handler**: `@bp.route('/dashboard')`
- **Session Management**: Flask session integration
- **Authentication Check**: User session validation
- **Logging**: Debug output for troubleshooting
##### Styling Classes
- `.dashboard-container`: Main container with responsive grid
- `.dashboard-card`: Individual module cards
- `.btn`: Standardized button styling
- Responsive breakpoints for mobile/tablet adaptation
### Usage Examples
#### Superadmin User Dashboard Access
```
Role: superadmin
Available Modules: All (Scanning, Quality, Warehouse, Labels, Settings)
Special Access: Settings module exclusive access
```
#### Quality Control User Dashboard Access
```
Role: quality
Available Modules: Quality Reports module only
Restricted Access: Cannot access other modules
```
#### Multi-Role Access Example
```
Role: warehouse
Available Modules: Warehouse module only
Access Pattern: Click → Permission Check → Module Access
```
---
*This documentation covers the dashboard system implementation. For specific module details, see their respective documentation sections.*

View File

@@ -1,161 +0,0 @@
#!/usr/bin/env python3
"""
Windows Print Service Connection Tester
Tests connectivity between Flask server and Windows Print Service
"""
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'app'))
import requests
import time
from app.print_config import WINDOWS_PRINT_SERVICE_URL, PRINT_SERVICE_TIMEOUT
def test_print_service_connection():
"""Test connection to Windows Print Service"""
print("=== Windows Print Service Connection Test ===\n")
print(f"🔍 Testing connection to: {WINDOWS_PRINT_SERVICE_URL}")
print(f"⏱️ Timeout: {PRINT_SERVICE_TIMEOUT} seconds")
print(f"🌐 From: Flask server (Linux)")
print(f"🎯 To: Windows Print Service")
print()
# Test 1: Health check
print("1⃣ Testing /health endpoint...")
try:
start_time = time.time()
response = requests.get(
f"{WINDOWS_PRINT_SERVICE_URL}/health",
timeout=PRINT_SERVICE_TIMEOUT
)
elapsed = time.time() - start_time
if response.status_code == 200:
data = response.json()
print(f" ✅ SUCCESS (Status: {response.status_code}, Time: {elapsed:.2f}s)")
print(f" 📋 Service: {data.get('service', 'Unknown')}")
print(f" 🖥️ Platform: {data.get('platform', 'Unknown')}")
print(f" 📅 Timestamp: {data.get('timestamp', 'Unknown')}")
health_ok = True
else:
print(f" ❌ FAILED (Status: {response.status_code})")
print(f" 📝 Response: {response.text}")
health_ok = False
except requests.exceptions.ConnectionError as e:
print(f" ❌ CONNECTION REFUSED")
print(f" 🔧 Error: {str(e)}")
print(f" 💡 This usually means:")
print(f" • Windows service is not running")
print(f" • Wrong IP address in configuration")
print(f" • Firewall blocking connection")
print(f" • Network routing issue")
health_ok = False
except Exception as e:
print(f" ❌ ERROR: {str(e)}")
health_ok = False
print()
# Test 2: Printers endpoint (only if health check passed)
if health_ok:
print("2⃣ Testing /printers endpoint...")
try:
response = requests.get(
f"{WINDOWS_PRINT_SERVICE_URL}/printers",
timeout=PRINT_SERVICE_TIMEOUT
)
if response.status_code == 200:
data = response.json()
printers = data.get('printers', [])
print(f" ✅ SUCCESS - Found {len(printers)} printer(s)")
for i, printer in enumerate(printers[:3]): # Show first 3
name = printer.get('name', 'Unknown') if isinstance(printer, dict) else printer
print(f" 🖨️ {i+1}. {name}")
if len(printers) > 3:
print(f" ... and {len(printers)-3} more")
else:
print(f" ❌ FAILED (Status: {response.status_code})")
except Exception as e:
print(f" ❌ ERROR: {str(e)}")
print()
# Test 3: Network diagnostics
print("3⃣ Network Diagnostics...")
# Parse URL to get host and port
try:
from urllib.parse import urlparse
parsed = urlparse(WINDOWS_PRINT_SERVICE_URL)
host = parsed.hostname
port = parsed.port or 8765
print(f" 🌐 Target Host: {host}")
print(f" 🔌 Target Port: {port}")
# Test DNS resolution
try:
import socket
ip = socket.gethostbyname(host)
print(f" 🔍 DNS Resolution: {host}{ip}")
dns_ok = True
except Exception as e:
print(f" ❌ DNS Resolution failed: {e}")
dns_ok = False
# Test raw TCP connection
if dns_ok:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex((host, port))
sock.close()
if result == 0:
print(f" ✅ TCP Connection: Port {port} is open")
else:
print(f" ❌ TCP Connection: Port {port} is closed or filtered")
print(f" 💡 Check Windows Firewall and service status")
except Exception as e:
print(f" ❌ TCP Test error: {e}")
except Exception as e:
print(f" ❌ URL parsing error: {e}")
print()
# Final recommendations
print("🔧 TROUBLESHOOTING RECOMMENDATIONS:")
print()
if not health_ok:
print("❌ CONNECTION FAILED - Try these steps:")
print("1. Verify Windows Print Service is running:")
print(" • Windows: sc query QualityLabelPrinting")
print(" • Or: Get-Service QualityLabelPrinting")
print()
print("2. Check Windows machine IP address:")
print(" • Windows: ipconfig | findstr IPv4")
print(" • Update WINDOWS_PRINT_SERVICE_URL in print_config.py")
print()
print("3. Test firewall:")
print(" • Windows: Allow port 8765 in Windows Firewall")
print(" • Test: telnet [WINDOWS_IP] 8765")
print()
print("4. If same machine, verify service binding:")
print(" • Service should bind to 0.0.0.0:8765 (not 127.0.0.1)")
else:
print("✅ CONNECTION SUCCESS - Print service should work!")
print("• Service is reachable and responding")
print("• Ready for label printing")
print("• Try printing labels from the web interface")
print(f"\n📝 Current Configuration:")
print(f" Service URL: {WINDOWS_PRINT_SERVICE_URL}")
print(f" Timeout: {PRINT_SERVICE_TIMEOUT}s")
return health_ok
if __name__ == "__main__":
test_print_service_connection()

View File

@@ -1,146 +0,0 @@
# Recticel Direct Print Service - Installation Guide
## 🎯 Overview
This service enables direct printing from web browsers to thermal label printers (Epson TM-T20, Citizen CTS-310, etc.) without requiring PDF generation or manual printer dialogs.
## 🔧 Installation Steps
### 1. **Build the C# Application**
**Requirements:**
- Visual Studio 2019 or later
- .NET Framework 4.7.2 or later
- Windows 10/11
**Build Steps:**
1. Open `RecticelPrintService.sln` in Visual Studio
2. Restore NuGet packages (Newtonsoft.Json)
3. Build in Release mode
4. Copy the entire `bin\Release` folder to `C:\RecticelPrintService\`
### 2. **Register the Custom Protocol**
**Option A: Double-click the registry file**
1. Right-click `recticel-print-protocol.reg`
2. Select "Run as administrator"
3. Confirm the registry import
**Option B: Manual registry import**
1. Open Command Prompt as Administrator
2. Run: `reg import "recticel-print-protocol.reg"`
### 3. **Install Printer Drivers**
**For Epson TM-T20:**
- Download and install Epson TM-T20 drivers from Epson website
- Configure printer as "Epson TM-T20" in Windows
**For Citizen CTS-310:**
- Download and install Citizen CTS-310 drivers
- Configure printer as "Citizen CTS-310" in Windows
### 4. **Configure Printer Settings**
1. Open Windows "Printers & scanners"
2. Set paper size to **80mm x 110mm** (or closest available)
3. Set print quality to **300 DPI** for thermal printers
4. Disable margins (set to 0 if possible)
### 5. **Test the Installation**
1. Open your web browser
2. Navigate to the print module page
3. Select an order
4. Choose "Direct Print" option
5. Select your thermal printer
6. Click "Print Labels"
## 🖨️ Printer Configuration
### Label Size Settings
- **Width**: 80mm
- **Height**: 110mm
- **Margins**: 0mm (all sides)
- **Print Quality**: 300 DPI
### Thermal Printer Specific Settings
**Epson TM-T20:**
- Paper Type: Continuous label
- Print Speed: Normal
- Print Density: Adjust based on label stock
**Citizen CTS-310:**
- Media Type: Label
- Print Method: Thermal Transfer or Direct Thermal
- Print Speed: Medium
## 🔄 How It Works
1. **Web Interface**: User selects order and clicks "Direct Print"
2. **Data Encoding**: Order data is encoded as Base64 JSON
3. **Custom Protocol**: Browser calls `recticel-print://printer/data`
4. **Service Activation**: Windows launches RecticelPrintService.exe
5. **Data Processing**: Service decodes and formats label data
6. **Direct Printing**: Label is sent directly to the thermal printer
7. **Status Update**: Database is updated to mark order as printed
## 🚀 URL Format
```
recticel-print://[printer_name]/[base64_encoded_json]
```
**Example:**
```
recticel-print://Epson%20TM-T20/eyJvcmRlcl9pZCI6MTIzLCJjb21hbmRhX3Byb2R1Y3RpZSI6IkNQMDAwMDA3MTEifQ==
```
## ⚠️ Troubleshooting
### Service Not Starting
1. Check if the service is installed in `C:\RecticelPrintService\`
2. Verify registry entries are correct
3. Run as Administrator if needed
### Printer Not Found
1. Check printer name in Windows exactly matches selection
2. Ensure printer drivers are installed
3. Test print from Windows to verify printer works
### Labels Not Printing
1. Verify paper size is set to 80x110mm
2. Check printer margins are set to 0
3. Ensure thermal paper is loaded correctly
### Browser Security
- Some browsers may block custom protocols
- Add site to trusted sites if needed
- Chrome may show a confirmation dialog
## 🔧 Advanced Configuration
### Custom Printer Names
Users can add custom printer names by selecting "Other Printer..." and entering the exact Windows printer name.
### Multiple Label Quantities
The service automatically prints the quantity specified in the order, with sequential numbering (CP00000711-001, CP00000711-002, etc.).
### Fallback to PDF
If direct printing fails, users can switch to "Generate PDF" mode for manual printing.
## 📞 Support
For technical support:
1. Check Windows Event Viewer for service errors
2. Verify printer connectivity and driver installation
3. Test with PDF generation mode as fallback
4. Contact IT support with specific error messages
## 🔒 Security Notes
- The service only processes label data from trusted sources
- Registry changes require Administrator privileges
- Service runs with current user permissions
- No network connections are made by the service

View File

@@ -1,24 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2046
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RecticelPrintService", "RecticelPrintService\RecticelPrintService.csproj", "{41ED6235-3C76-4723-A5F6-02D2FA51E677}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{41ED6235-3C76-4723-A5F6-02D2FA51E677}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41ED6235-3C76-4723-A5F6-02D2FA51E677}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41ED6235-3C76-4723-A5F6-02D2FA51E677}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41ED6235-3C76-4723-A5F6-02D2FA51E677}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FC401D2A-E68E-47EE-B315-E1A2F0B292FA}
EndGlobalSection
EndGlobal

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

View File

@@ -1,288 +0,0 @@
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Text;
using Newtonsoft.Json;
namespace RecticelPrintService
{
public class LabelPrinter
{
private PrintData _labelData;
// Label dimensions in millimeters (80x110mm)
private const float LABEL_WIDTH_MM = 80f;
private const float LABEL_HEIGHT_MM = 110f;
// Convert mm to hundredths of an inch (used by .NET printing)
private float MmToHundredthsOfInch(float mm)
{
return mm * 3.937f; // 1mm = 0.03937 inches, * 100 for hundredths
}
public bool PrintLabel(string printerName, string jsonData)
{
try
{
// Parse JSON data
_labelData = JsonConvert.DeserializeObject<PrintData>(jsonData);
if (_labelData == null)
{
Console.WriteLine("Failed to parse JSON data");
return false;
}
// Set up print document
PrintDocument printDoc = new PrintDocument();
printDoc.PrinterSettings.PrinterName = printerName;
// Check if printer exists
if (!printDoc.PrinterSettings.IsValid)
{
Console.WriteLine($"Printer '{printerName}' not found or not available");
Console.WriteLine("Available printers:");
foreach (string printer in PrinterSettings.InstalledPrinters)
{
Console.WriteLine($" - {printer}");
}
return false;
}
// Set paper size for 80x110mm labels
PaperSize labelSize = new PaperSize("Label 80x110mm",
(int)MmToHundredthsOfInch(LABEL_WIDTH_MM),
(int)MmToHundredthsOfInch(LABEL_HEIGHT_MM));
printDoc.DefaultPageSettings.PaperSize = labelSize;
printDoc.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
// Set print event handler
printDoc.PrintPage += PrintDoc_PrintPage;
// Print the document
printDoc.Print();
return true;
}
catch (Exception ex)
{
Console.WriteLine($"Error printing label: {ex.Message}");
return false;
}
}
private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
{
try
{
Graphics g = e.Graphics;
// Define fonts
Font companyFont = new Font("Arial", 10, FontStyle.Bold);
Font headerFont = new Font("Arial", 8, FontStyle.Bold);
Font dataFont = new Font("Arial", 9, FontStyle.Bold);
Font labelFont = new Font("Arial", 7);
Font barcodeFont = new Font("Courier New", 6, FontStyle.Bold);
// Define brushes and pens
Brush textBrush = Brushes.Black;
Pen borderPen = new Pen(Color.Black, 2);
Pen dividerPen = new Pen(Color.Gray, 1);
// Calculate positions (in pixels, 300 DPI assumed)
float dpiX = e.Graphics.DpiX;
float dpiY = e.Graphics.DpiY;
// Convert mm to pixels
float labelWidth = (LABEL_WIDTH_MM / 25.4f) * dpiX;
float labelHeight = (LABEL_HEIGHT_MM / 25.4f) * dpiY;
// Content area (similar to your HTML preview)
float contentX = (3f / 25.4f) * dpiX; // 3mm margin
float contentY = (15f / 25.4f) * dpiY; // 15mm from bottom
float contentWidth = (60f / 25.4f) * dpiX; // 60mm width
float contentHeight = (85f / 25.4f) * dpiY; // 85mm height
// Draw main content border
g.DrawRectangle(borderPen, contentX, contentY, contentWidth, contentHeight);
// Calculate row height
float rowHeight = contentHeight / 10f; // 9 rows + spacing
float currentY = contentY;
// Row 1: Company Header
string companyText = "INNOFA RROMANIA SRL";
SizeF companySize = g.MeasureString(companyText, companyFont);
float companyX = contentX + (contentWidth - companySize.Width) / 2;
g.DrawString(companyText, companyFont, textBrush, companyX, currentY + rowHeight/3);
currentY += rowHeight;
// Horizontal divider after company
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Row 2: Customer Name
string customerName = _labelData.CustomerName ?? "N/A";
SizeF customerSize = g.MeasureString(customerName, headerFont);
float customerX = contentX + (contentWidth - customerSize.Width) / 2;
g.DrawString(customerName, headerFont, textBrush, customerX, currentY + rowHeight/3);
currentY += rowHeight;
// Horizontal divider after customer
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Vertical divider (40% from left)
float verticalDividerX = contentX + contentWidth * 0.4f;
g.DrawLine(dividerPen, verticalDividerX, currentY, verticalDividerX, contentY + contentHeight);
// Row 3: Quantity
g.DrawString("Quantity ordered", labelFont, textBrush, contentX + 5, currentY + rowHeight/4);
string quantity = _labelData.Cantitate.ToString();
SizeF qtySize = g.MeasureString(quantity, dataFont);
float qtyX = verticalDividerX + (contentWidth * 0.6f - qtySize.Width) / 2;
g.DrawString(quantity, dataFont, textBrush, qtyX, currentY + rowHeight/4);
currentY += rowHeight;
// Horizontal divider
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Row 4: Customer Order
g.DrawString("Customer order", labelFont, textBrush, contentX + 5, currentY + rowHeight/4);
string customerOrder = $"{_labelData.ComAchizClient}-{_labelData.NrLinieComClient}";
if (string.IsNullOrEmpty(_labelData.ComAchizClient)) customerOrder = "N/A";
SizeF orderSize = g.MeasureString(customerOrder, dataFont);
float orderX = verticalDividerX + (contentWidth * 0.6f - orderSize.Width) / 2;
g.DrawString(customerOrder, dataFont, textBrush, orderX, currentY + rowHeight/4);
currentY += rowHeight;
// Horizontal divider
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Row 5: Delivery Date
g.DrawString("Delivery date", labelFont, textBrush, contentX + 5, currentY + rowHeight/4);
string deliveryDate = _labelData.DataLivrare ?? "N/A";
if (!string.IsNullOrEmpty(deliveryDate) && deliveryDate != "N/A")
{
try
{
DateTime dt = DateTime.Parse(deliveryDate);
deliveryDate = dt.ToString("dd/MM/yyyy");
}
catch { }
}
SizeF dateSize = g.MeasureString(deliveryDate, dataFont);
float dateX = verticalDividerX + (contentWidth * 0.6f - dateSize.Width) / 2;
g.DrawString(deliveryDate, dataFont, textBrush, dateX, currentY + rowHeight/4);
currentY += rowHeight;
// Horizontal divider
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Row 6: Description (double height)
g.DrawString("Description", labelFont, textBrush, contentX + 5, currentY + rowHeight/4);
string description = _labelData.DescrComProd ?? "N/A";
// Word wrap description if needed
RectangleF descRect = new RectangleF(verticalDividerX + 5, currentY + 5,
contentWidth * 0.6f - 10, rowHeight * 2 - 10);
g.DrawString(description, dataFont, textBrush, descRect);
currentY += rowHeight * 2;
// Horizontal divider
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Row 7: Size
g.DrawString("Size", labelFont, textBrush, contentX + 5, currentY + rowHeight/4);
string size = _labelData.Dimensiune ?? "N/A";
SizeF sizeSize = g.MeasureString(size, dataFont);
float sizeX = verticalDividerX + (contentWidth * 0.6f - sizeSize.Width) / 2;
g.DrawString(size, dataFont, textBrush, sizeX, currentY + rowHeight/4);
currentY += rowHeight;
// Horizontal divider
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Row 8: Article Code
g.DrawString("Article Code", labelFont, textBrush, contentX + 5, currentY + rowHeight/4);
string articleCode = _labelData.CustomerArticleNumber ?? "N/A";
SizeF artSize = g.MeasureString(articleCode, dataFont);
float artX = verticalDividerX + (contentWidth * 0.6f - artSize.Width) / 2;
g.DrawString(articleCode, dataFont, textBrush, artX, currentY + rowHeight/4);
currentY += rowHeight;
// Horizontal divider
g.DrawLine(dividerPen, contentX, currentY, contentX + contentWidth, currentY);
// Row 9: Prod Order
g.DrawString("Prod Order", labelFont, textBrush, contentX + 5, currentY + rowHeight/4);
string prodOrder = _labelData.SequentialNumber ?? $"{_labelData.ComandaProductie}-{_labelData.Cantitate}";
SizeF prodSize = g.MeasureString(prodOrder, dataFont);
float prodX = verticalDividerX + (contentWidth * 0.6f - prodSize.Width) / 2;
g.DrawString(prodOrder, dataFont, textBrush, prodX, currentY + rowHeight/4);
// Bottom barcode area
float barcodeY = contentY + contentHeight + (5f / 25.4f) * dpiY; // 5mm below content
float barcodeWidth = contentWidth;
float barcodeHeight = (10f / 25.4f) * dpiY; // 10mm height
// Draw barcode representation (simple lines)
DrawSimpleBarcode(g, contentX, barcodeY, barcodeWidth, barcodeHeight, prodOrder);
// Barcode text
SizeF barcodeTextSize = g.MeasureString(prodOrder, barcodeFont);
float barcodeTextX = contentX + (contentWidth - barcodeTextSize.Width) / 2;
g.DrawString(prodOrder, barcodeFont, textBrush, barcodeTextX, barcodeY + barcodeHeight + 5);
// Vertical barcode on the right side
float verticalBarcodeX = contentX + contentWidth + (5f / 25.4f) * dpiX; // 5mm to the right
float verticalBarcodeWidth = (8f / 25.4f) * dpiX; // 8mm width
DrawSimpleVerticalBarcode(g, verticalBarcodeX, contentY + rowHeight * 2,
verticalBarcodeWidth, contentHeight - rowHeight * 2, customerOrder);
// Dispose resources
companyFont.Dispose();
headerFont.Dispose();
dataFont.Dispose();
labelFont.Dispose();
barcodeFont.Dispose();
borderPen.Dispose();
dividerPen.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"Error in PrintPage event: {ex.Message}");
}
}
private void DrawSimpleBarcode(Graphics g, float x, float y, float width, float height, string data)
{
// Simple barcode representation using alternating lines
float barWidth = 2f;
bool drawBar = true;
for (float currentX = x; currentX < x + width; currentX += barWidth)
{
if (drawBar)
{
g.FillRectangle(Brushes.Black, currentX, y, barWidth, height * 0.8f);
}
drawBar = !drawBar;
}
}
private void DrawSimpleVerticalBarcode(Graphics g, float x, float y, float width, float height, string data)
{
// Simple vertical barcode representation
float barHeight = 2f;
bool drawBar = true;
for (float currentY = y; currentY < y + height; currentY += barHeight)
{
if (drawBar)
{
g.FillRectangle(Brushes.Black, x, currentY, width * 0.8f, barHeight);
}
drawBar = !drawBar;
}
}
}
}

View File

@@ -1,49 +0,0 @@
using Newtonsoft.Json;
namespace RecticelPrintService
{
public class PrintData
{
[JsonProperty("order_id")]
public int OrderId { get; set; }
[JsonProperty("comanda_productie")]
public string ComandaProductie { get; set; }
[JsonProperty("customer_name")]
public string CustomerName { get; set; }
[JsonProperty("cantitate")]
public int Cantitate { get; set; }
[JsonProperty("com_achiz_client")]
public string ComAchizClient { get; set; }
[JsonProperty("nr_linie_com_client")]
public string NrLinieComClient { get; set; }
[JsonProperty("data_livrare")]
public string DataLivrare { get; set; }
[JsonProperty("dimensiune")]
public string Dimensiune { get; set; }
[JsonProperty("descr_com_prod")]
public string DescrComProd { get; set; }
[JsonProperty("customer_article_number")]
public string CustomerArticleNumber { get; set; }
[JsonProperty("cod_articol")]
public string CodArticol { get; set; }
[JsonProperty("sequential_number")]
public string SequentialNumber { get; set; }
[JsonProperty("current_label")]
public int CurrentLabel { get; set; }
[JsonProperty("total_labels")]
public int TotalLabels { get; set; }
}
}

View File

@@ -1,81 +0,0 @@
using System;
using System.Web;
namespace RecticelPrintService
{
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length == 0)
{
Console.WriteLine("Recticel Print Service - No arguments provided");
Console.WriteLine("Usage: RecticelPrintService.exe \"recticel-print://printer/data\"");
Console.ReadKey();
return;
}
string url = args[0];
Console.WriteLine($"Received print request: {url}");
// Parse the custom protocol URL
// Format: recticel-print://printer_name/base64_encoded_json_data
if (!url.StartsWith("recticel-print://"))
{
Console.WriteLine("Invalid protocol. Expected: recticel-print://");
Console.ReadKey();
return;
}
// Remove protocol prefix
string data = url.Substring("recticel-print://".Length);
// Split printer name and data
string[] parts = data.Split('/');
if (parts.Length < 2)
{
Console.WriteLine("Invalid URL format. Expected: recticel-print://printer_name/data");
Console.ReadKey();
return;
}
string printerName = HttpUtility.UrlDecode(parts[0]);
string encodedData = HttpUtility.UrlDecode(parts[1]);
Console.WriteLine($"Target Printer: {printerName}");
Console.WriteLine($"Data Length: {encodedData.Length}");
// Decode base64 JSON data
byte[] dataBytes = Convert.FromBase64String(encodedData);
string jsonData = System.Text.Encoding.UTF8.GetString(dataBytes);
Console.WriteLine($"Decoded JSON: {jsonData}");
// Parse and print the label
var printer = new LabelPrinter();
bool success = printer.PrintLabel(printerName, jsonData);
if (success)
{
Console.WriteLine("✅ Label printed successfully!");
}
else
{
Console.WriteLine("❌ Failed to print label!");
}
// Keep console open for debugging (remove in production)
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
Console.WriteLine(ex.StackTrace);
Console.ReadKey();
}
}
}
}

View File

@@ -1,19 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("RecticelPrintService")]
[assembly: AssemblyDescription("Direct label printing service for Recticel Quality System")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Recticel")]
[assembly: AssemblyProduct("Recticel Print Service")]
[assembly: AssemblyCopyright("Copyright © Recticel 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("41ed6235-3c76-4723-a5f6-02d2fa51e677")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,62 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{41ED6235-3C76-4723-A5F6-02D2FA51E677}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>RecticelPrintService</RootNamespace>
<AssemblyName>RecticelPrintService</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Drawing.Printing" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="LabelPrinter.cs" />
<Compile Include="PrintData.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
</packages>

View File

@@ -1,50 +0,0 @@
@echo off
echo Installing Recticel Print Service...
echo.
REM Check if running as Administrator
net session >nul 2>&1
if %errorlevel% neq 0 (
echo ERROR: This script must be run as Administrator.
echo Right-click and select "Run as administrator"
pause
exit /b 1
)
REM Create installation directory
echo Creating installation directory...
if not exist "C:\RecticelPrintService" (
mkdir "C:\RecticelPrintService"
)
REM Copy files (assuming this script is in the same directory as the built application)
echo Copying application files...
copy "RecticelPrintService\bin\Release\*.*" "C:\RecticelPrintService\" /Y
REM Register custom protocol
echo Registering custom protocol...
reg import "recticel-print-protocol.reg"
if %errorlevel% equ 0 (
echo.
echo ✅ Installation completed successfully!
echo.
echo Service installed to: C:\RecticelPrintService\
echo Protocol registered: recticel-print://
echo.
echo Next steps:
echo 1. Configure your thermal label printer in Windows
echo 2. Set label size to 80mm x 110mm
echo 3. Test printing from the web interface
echo.
echo Press any key to exit...
pause >nul
) else (
echo.
echo ❌ Installation failed!
echo Please check if you're running as Administrator.
echo.
pause
)
exit /b 0

View File

@@ -1,14 +0,0 @@
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\recticel-print]
@="URL:Recticel Print Protocol"
"URL Protocol"=""
"EditFlags"=dword:00000002
[HKEY_CLASSES_ROOT\recticel-print\shell]
@="open"
[HKEY_CLASSES_ROOT\recticel-print\shell\open]
[HKEY_CLASSES_ROOT\recticel-print\shell\open\command]
@="\"C:\\RecticelPrintService\\RecticelPrintService.exe\" \"%1\""

View File

@@ -1,224 +0,0 @@
# Windows Service Error 1053 - COMPLETE FIX PACKAGE
## 🎯 Problem Description
**Windows Service Error 1053**: "The service did not respond to the start or control request in a timely fashion."
This error occurs when:
- Service takes too long to respond to Windows Service Control Manager (SCM)
- Python process doesn't communicate properly with Windows services
- Service wrapper doesn't handle SCM signals correctly
- Dependencies or paths are incorrect
## 📦 Complete Solution Package
This package provides **4 different installation methods** and comprehensive Error 1053 fixes:
### 🔧 Installation Files
1. **`install_service_ENHANCED.bat`** - Main installer with multiple fallback methods
2. **`fix_error_1053.bat`** - Dedicated Error 1053 diagnostic and fix tool
3. **`print_service_complete.py`** - Enhanced service with proper Windows service support
4. **`service_wrapper.py`** - Optional advanced service wrapper
5. **`test_service.bat`** - Standalone testing tool
### 🚀 Installation Methods (Automatic Fallback)
#### Method 1: Windows SC Service (Preferred)
- Creates standard Windows service
- Includes enhanced timeout handling
- Automatic recovery configuration
- **Fixes Error 1053** with proper SCM communication
#### Method 2: Task Scheduler Service (Fallback)
- Runs as scheduled task on system startup
- SYSTEM privileges with highest elevation
- Automatic restart on failure
- Bypasses SCM timeout issues
#### Method 3: Startup Script (Manual Fallback)
- Runs from Windows startup folder
- Simple and reliable
- Manual process management
- Always works as final resort
#### Method 4: Standalone Mode (Testing/Debugging)
- Direct Python execution
- No Windows service wrapper
- Immediate startup for testing
- Perfect for troubleshooting
## 🔍 Error 1053 Specific Fixes
### Root Cause Analysis
The enhanced installers address these Error 1053 causes:
1. **SCM Timeout Issues**
- Enhanced service wrapper responds immediately to SCM
- Service process starts in background
- Proper exit codes and signaling
2. **Python Path Problems**
- Automatic detection of embedded Python
- Fallback to system Python
- Absolute path resolution
3. **Service Communication**
- Proper Windows service signal handling
- Enhanced logging and error reporting
- Background process management
4. **Dependency Issues**
- Self-contained Python environment
- Zero external dependencies
- Embedded Python distribution included
### Technical Implementation
#### Enhanced Service Wrapper
```batch
# error_1053_fix_wrapper.bat
- Immediate SCM response
- Background service startup
- Enhanced error handling
- Comprehensive logging
```
#### Service Configuration
```cmd
# Delayed auto-start to prevent startup conflicts
sc config QualityPrintService start= delayed-auto
# Automatic recovery on failure
sc failure QualityPrintService reset= 86400 actions= restart/5000/restart/5000/restart/5000
```
## 📋 Usage Instructions
### 🎯 Quick Fix (Recommended)
1. **Run as Administrator**: `fix_error_1053.bat`
2. This script will:
- Diagnose the current problem
- Apply all Error 1053 fixes
- Test service functionality
- Install with enhanced wrapper
### 🔧 Fresh Installation
1. **Run as Administrator**: `install_service_ENHANCED.bat`
2. Installer will automatically:
- Try Windows SC Service first
- Fall back to Task Scheduler if needed
- Create startup script as final option
- Test all methods until one succeeds
### 🧪 Testing and Verification
1. **Test standalone**: `test_service.bat`
2. **Manual testing**:
```cmd
cd C:\QualityPrintService
python print_service_complete.py --test
python print_service_complete.py --standalone
```
3. **Service status**:
```cmd
sc query QualityPrintService
net start QualityPrintService
```
## 🔍 Troubleshooting Guide
### If Error 1053 Still Occurs
1. **Run Diagnostic Tool**:
```cmd
fix_error_1053.bat
```
2. **Check Logs**:
- `%USERPROFILE%\PrintService\logs\service_wrapper.log`
- `%USERPROFILE%\PrintService\logs\error_1053_fix.log`
3. **Manual Service Test**:
```cmd
C:\QualityPrintService\error_1053_fix_wrapper.bat
```
4. **Alternative Installation**:
- Use Task Scheduler method
- Use Startup Script method
- Run in standalone mode
### Common Issues and Solutions
| Issue | Solution |
|-------|----------|
| "Python not found" | Use embedded Python package or install Python 3.7+ |
| "Port 8765 in use" | Stop existing services, reboot system |
| "Access denied" | Run installer as Administrator |
| "Service won't start" | Use Task Scheduler fallback method |
| "Still Error 1053" | Use startup script or standalone mode |
## ✅ Success Verification
After installation, verify success:
1. **Service Status**: Service should be "RUNNING"
```cmd
sc query QualityPrintService
```
2. **Network Test**: Should return "OK"
```cmd
curl http://localhost:8765/health
```
3. **Browser Test**: Open `http://localhost:8765/health`
4. **Chrome Extension**: Should connect successfully
## 📊 Package Contents Summary
### Core Service Files
- ✅ `print_service_complete.py` - Main service with Windows service support
- ✅ `service_wrapper.py` - Advanced service wrapper (optional)
- ✅ Enhanced service wrappers with Error 1053 fixes
### Installation Tools
- ✅ `install_service_ENHANCED.bat` - Multi-method installer
- ✅ `fix_error_1053.bat` - Dedicated Error 1053 fixer
- ✅ `test_service.bat` - Standalone testing tool
### Zero Dependencies
- ✅ `python_embedded/` - Complete Python 3.11.9 distribution
- ✅ No external dependencies required
- ✅ Self-contained package (10.8MB)
### Browser Integration
- ✅ `chrome_extension/` - Complete Chrome extension
- ✅ Automatic printer detection
- ✅ PDF processing and printing
## 🎯 Expected Results
After running the enhanced installer:
✅ **Windows Service Error 1053 RESOLVED**
✅ **Service starts automatically on boot**
✅ **Multiple installation methods available**
✅ **Comprehensive error handling and recovery**
✅ **Zero external dependencies**
✅ **Complete diagnostic and troubleshooting tools**
## 🚀 Next Steps
1. **Install**: Run `install_service_ENHANCED.bat` as Administrator
2. **Verify**: Check service status and network connectivity
3. **Configure**: Install Chrome extension from `chrome_extension/`
4. **Test**: Print labels from web application
5. **Monitor**: Check logs for any issues
The enhanced package provides **4 installation methods** and **comprehensive Error 1053 fixes** to ensure reliable service operation on all Windows systems.
---
**Support**: All installation methods include detailed logging and diagnostic information to troubleshoot any remaining issues.

View File

@@ -1,273 +0,0 @@
# Quality Print Service - Complete Installation Guide
## 🎯 Pre-Installation Checklist
### System Requirements Verification:
- [ ] Windows 10 build 1903+ or Windows Server 2016+
- [ ] Administrator access to the system
- [ ] Google Chrome browser installed
- [ ] At least 100 MB free disk space
- [ ] Network/USB printer connected and configured
### Python Requirements:
- [ ] Python 3.7+ installed OR use included portable Python
- [ ] Python accessible via command line (optional)
## 📦 Installation Methods
### Method 1: Complete Automatic Installation (Recommended)
1. **Download and Extract**:
- Extract the complete package to any folder (e.g., Desktop)
- No need to keep the files permanently
2. **Run Installer**:
```
Right-click: install_service_complete.bat
Select: "Run as administrator"
```
3. **Follow Installation Steps**:
```
[1/6] Administrator privileges confirmed ✓
[2/6] Checking Python installation...
[3/6] Creating installation directories...
[4/6] Installing service files...
[5/6] Installing Windows service...
[6/6] Starting service...
```
4. **Install Chrome Extension**:
- Chrome will open the extension folder automatically
- Go to `chrome://extensions/`
- Enable "Developer mode" (top right)
- Click "Load unpacked"
- Select the `chrome_extension` folder
5. **Verify Installation**:
- Visit: `http://localhost:8765/health`
- Expected response: `{"status": "healthy"}`
### Method 2: Manual Installation
1. **Create Directories**:
```cmd
mkdir C:\QualityPrintService
mkdir %USERPROFILE%\PrintService\logs
```
2. **Copy Files**:
```cmd
copy print_service_complete.py C:\QualityPrintService ```
3. **Install Service**:
```cmd
sc create QualityPrintService binPath="python C:\QualityPrintService\print_service_complete.py"
sc start QualityPrintService
```
## 🔧 Post-Installation Configuration
### Service Verification:
```cmd
# Check service status
sc query QualityPrintService
# Check service configuration
sc qc QualityPrintService
# View service logs (if using NSSM)
type "%USERPROFILE%\PrintService\logs\service_output.log"
```
### Network Testing:
```powershell
# Test health endpoint
Invoke-RestMethod -Uri http://localhost:8765/health
# Test printer endpoint
Invoke-RestMethod -Uri http://localhost:8765/printers
# Test from browser
start http://localhost:8765/status
```
### Chrome Extension Setup:
1. Open Chrome browser
2. Navigate to `chrome://extensions/`
3. Enable "Developer mode" toggle (top-right corner)
4. Click "Load unpacked" button
5. Browse and select the `chrome_extension` folder
6. Verify extension appears in the list with green toggle
## 🔍 Installation Verification
### Health Check Procedure:
1. **Service Status**: Verify Windows service is running
```cmd
sc query QualityPrintService | find "RUNNING"
```
2. **Network Connectivity**: Test HTTP endpoints
```cmd
curl http://localhost:8765/health
```
3. **Printer Detection**: Check printer enumeration
```cmd
curl http://localhost:8765/printers
```
4. **Extension Communication**: Test from web page
- Open the Quality app in Chrome
- Go to print module
- Verify "Extension ready" status
### Expected Responses:
**Health Check**:
```json
{
"status": "healthy",
"service": "Windows Print Service",
"version": "1.0.0",
"timestamp": "2025-09-25T10:30:00"
}
```
**Printer List**:
```json
{
"success": true,
"printers": [
{"name": "HP LaserJet", "type": "Local", "status": "Available"}
],
"count": 1
}
```
## 🚨 Troubleshooting Common Issues
### Issue: "Administrator privileges required"
**Solution**:
- Right-click installer file
- Select "Run as administrator"
- Confirm UAC prompt
### Issue: "Python not found"
**Solutions**:
1. Install Python from python.org
2. Use included portable Python
3. Add Python to system PATH
### Issue: "Service failed to start"
**Solutions**:
1. Check Windows Event Viewer:
- Windows Logs → Application
- Filter by source: "Service Control Manager"
2. Verify port 8765 is not in use:
```cmd
netstat -an | find "8765"
```
3. Check service logs:
```cmd
type "%USERPROFILE%\PrintService\logs\print_service_*.log"
```
### Issue: "Chrome extension not working"
**Solutions**:
1. Reload extension in `chrome://extensions/`
2. Check extension permissions
3. Verify service is responding at `localhost:8765`
4. Clear browser cache and cookies
### Issue: "PDF printing fails"
**Solutions**:
1. Install Adobe Reader or SumatraPDF
2. Check printer permissions
3. Verify PDF file accessibility
4. Test with different printer
## 🔄 Maintenance and Updates
### Regular Maintenance:
- **Log Cleanup**: Logs rotate automatically
- **Service Monitoring**: Check service status weekly
- **Chrome Extension**: Update when prompted
### Manual Service Management:
```cmd
# Stop service
sc stop QualityPrintService
# Start service
sc start QualityPrintService
# Restart service
sc stop QualityPrintService && timeout /t 3 && sc start QualityPrintService
# Change startup type
sc config QualityPrintService start= auto
```
### Log File Locations:
- Service logs: `%USERPROFILE%\PrintService\logs\`
- Windows Event Logs: Event Viewer → Windows Logs → Application
- Chrome Extension: Chrome DevTools → Console
## 🔧 Advanced Configuration
### Custom Port Configuration:
Edit `print_service_complete.py`:
```python
server_address = ('localhost', 8765) # Change 8765 to desired port
```
### Custom Install Directory:
Edit `install_service_complete.bat`:
```batch
set INSTALL_DIR=C:\CustomPath\PrintService
```
### Service Recovery Options:
```cmd
sc failure QualityPrintService reset= 86400 actions= restart/5000/restart/10000/restart/30000
```
## 📋 Uninstallation
### Complete Removal:
1. Run `uninstall_service_complete.bat` as Administrator
2. Remove Chrome extension manually
3. Optional: Delete log files
### Manual Removal:
```cmd
# Stop and remove service
sc stop QualityPrintService
sc delete QualityPrintService
# Remove files
rmdir /s /q C:\QualityPrintService
rmdir /s /q "%USERPROFILE%\PrintService"
```
## 📞 Getting Help
### Before Contacting Support:
1. Check this installation guide
2. Review troubleshooting section
3. Check service logs for error messages
4. Test with simple printer (like Microsoft Print to PDF)
### Information to Provide:
- Windows version (run `winver`)
- Python version (run `python --version`)
- Service status (run `sc query QualityPrintService`)
- Recent log entries
- Error messages or screenshots
---
**Installation Guide Version**: 1.0.0
**Last Updated**: September 2025
**Support**: Internal Quality System Team

View File

@@ -1,193 +0,0 @@
# Quality Windows Print Service - Complete Self-Contained Package Summary
## 📦 Package Overview
This is a **complete, self-contained Windows print service** with **zero external dependencies** that enables silent PDF printing from the Quality Label web application.
## 🎯 Key Features
### ✅ Zero Dependencies
- Uses **only Python standard library** (no external packages required)
- Works with **any Python 3.7+** installation (system or portable)
- No complicated setup or package management
### ✅ Complete Windows Integration
- **Windows Service** with automatic startup
- **Service recovery** with auto-restart on failure
- **Professional logging** with daily rotation
- **Chrome extension** for seamless web integration
### ✅ Multiple Printing Methods (Automatic Fallback)
1. **Adobe Reader** command line printing
2. **SumatraPDF** automation
3. **PowerShell** printing commands
4. **Microsoft Edge** integration
5. **Windows system default** application
### ✅ Robust Architecture
```
Quality Web App → Chrome Extension → Windows Service → Physical Printer
(localhost only) (port 8765) (any printer)
```
## 📁 Package Contents
### Core Service Files:
- `print_service_complete.py` - Main service (19KB, pure Python)
- `install_service_complete.bat` - Complete installer with Python detection
- `uninstall_service_complete.bat` - Clean removal script
- `requirements_complete.txt` - Dependencies list (all standard library)
### Chrome Extension:
- `chrome_extension/manifest.json` - Extension configuration
- `chrome_extension/background.js` - Windows service communication
- `chrome_extension/popup.html` - Extension interface
- `chrome_extension/popup.js` - Extension functionality
### Documentation:
- `README_COMPLETE.md` - Comprehensive technical documentation
- `INSTALLATION_COMPLETE.md` - Step-by-step installation guide
- `PORTABLE_PYTHON_INSTRUCTIONS.txt` - Python distribution options
### Build Tools:
- `build_package.py` - Package builder and documentation generator
- `build_executable.bat` - Optional standalone .exe builder
## 🚀 Installation Process (5 Minutes)
### Prerequisites:
- Windows 10/11 or Windows Server 2016+
- Administrator privileges
- Google Chrome browser
- Python 3.7+ (system or portable)
### Steps:
1. **Extract Package** - Extract ZIP to any temporary location
2. **Run Installer** - Right-click `install_service_complete.bat` → "Run as administrator"
3. **Install Extension** - Load `chrome_extension` folder in Chrome
4. **Test Service** - Visit http://localhost:8765/health
## 🔧 Technical Specifications
### Service Details:
- **Port**: 8765 (localhost only for security)
- **Memory Usage**: ~15-30 MB
- **CPU Usage**: <1% (idle)
- **Installation Path**: `C:\QualityPrintService\`
- **Logs**: `%USERPROFILE%\PrintService\logs\`
### API Endpoints:
- `GET /health` - Service health check and status
- `GET /printers` - List available system printers
- `GET /status` - Service statistics and uptime
- `POST /print_pdf` - Print PDF file (supports page-by-page)
### Printing Workflow:
1. User selects order in Quality web app
2. User clicks "Print Labels"
3. Chrome extension detects Windows service
4. PDF is generated and sent to service
5. Service downloads PDF and prints using best available method
6. Temporary files are automatically cleaned up
## 🛡️ Security & Reliability
### Security Features:
- **Localhost only** - Service only accepts connections from 127.0.0.1
- **No external network** - All communication is local
- **Secure PDF handling** - Temporary files with auto-cleanup
- **Extension origin validation** - Chrome extension verifies sender origins
### Reliability Features:
- **Service recovery** - Auto-restart on failure (3 attempts)
- **Multiple print methods** - Automatic fallback if one method fails
- **Error logging** - Comprehensive error tracking and debugging
- **Health monitoring** - Built-in health checks and status reporting
## 📈 Advantages Over Previous Approaches
### vs Chrome-Only Printing:
-**No browser security restrictions**
-**True silent printing** (no print dialogs)
-**Reliable printer selection**
-**Page-by-page printing support**
### vs PowerShell-Only Service:
-**More portable** (works without PowerShell expertise)
-**Better error handling** and logging
-**More printing methods** available
-**Easier debugging** and maintenance
### vs External Dependencies:
-**Zero package management** complexity
-**No version conflicts** or update issues
-**Works on restricted systems**
-**Smaller footprint** and faster startup
## 🎯 Why This Solution Works
### For IT Administrators:
- **Simple deployment** - One ZIP file, one installer command
- **Professional service** - Proper Windows service with logging
- **Easy maintenance** - Self-contained with automatic recovery
- **Security compliant** - Localhost only, no external dependencies
### For End Users:
- **Transparent operation** - Just click print, labels appear
- **No manual steps** - No print dialogs or file management
- **Reliable printing** - Multiple fallback methods ensure success
- **Professional interface** - Clean integration with Quality app
### For Developers:
- **Clean architecture** - Clear separation of concerns
- **Extensible design** - Easy to add new printing methods
- **Comprehensive logging** - Full debugging and monitoring
- **Standard protocols** - HTTP API for easy integration
## 🔮 Future Enhancements
### Planned Features:
- **Print queue management** - View and manage pending jobs
- **Printer status monitoring** - Real-time printer health checks
- **Print job history** - Track completed and failed jobs
- **Configuration GUI** - Windows app for service settings
### Optional Add-ons:
- **Standalone .exe** - Single file deployment (using PyInstaller)
- **MSI installer** - Enterprise deployment package
- **Network printing** - Remote printer support
- **Print templates** - Custom label formats
## 📊 Installation Statistics
### Installation Time: **~5 minutes**
- Package extraction: 30 seconds
- Service installation: 2 minutes
- Chrome extension: 1 minute
- Testing and verification: 1.5 minutes
### Maintenance Required: **Zero**
- Auto-starts with Windows
- Self-recovery on failure
- Automatic log rotation
- No user intervention needed
## 🎉 Ready for Production
This package is **production-ready** and includes:
- ✅ Complete installation automation
- ✅ Professional error handling
- ✅ Comprehensive documentation
- ✅ Testing and verification tools
- ✅ Clean uninstallation process
**The Quality Windows Print Service provides enterprise-grade label printing with consumer-friendly simplicity.**
---
**Package Version**: 1.0.0 Complete
**Build Date**: September 25, 2025
**Python Compatibility**: 3.7+ (all versions)
**Windows Compatibility**: Windows 10+ / Server 2016+
**Chrome Compatibility**: All recent versions
**Status**: ✅ Production Ready - Zero Dependencies - Self Contained

View File

@@ -1,39 +0,0 @@
# PORTABLE PYTHON PACKAGE INSTRUCTIONS
To create a complete self-contained package, you need to include a portable Python interpreter.
## Option 1: Download Embedded Python (Recommended)
1. Download Python 3.11 Embedded from: https://www.python.org/downloads/windows/
2. Choose "Windows embeddable package (64-bit)" or "(32-bit)"
3. Extract to a folder named 'python_portable'
4. The structure should be:
python_portable/
├── python.exe
├── python311.dll (or similar)
├── pythoncom311.dll
└── ... (other Python files)
## Option 2: Use PyInstaller (Alternative)
1. Install PyInstaller: pip install pyinstaller
2. Run: pyinstaller --onefile --noconsole print_service_complete.py
3. This creates a single .exe file with all dependencies
## Option 3: Manual Python Installation Check
The installer will check for system Python and use it if available.
## Current Package Structure
This package includes:
✓ Complete Python script with all dependencies
✓ Windows service installer
✓ Chrome extension
✓ Logging and error handling
✓ Multiple printing method fallbacks
✓ Automatic recovery options
## Dependencies Included in Python Script:
- All standard library modules (http.server, json, subprocess, etc.)
- No external dependencies required
- Pure Python implementation
The service will work with any Python 3.7+ installation.

View File

@@ -1,167 +0,0 @@
# Quality Windows Print Service - Complete Self-Contained Package
## 🎯 Overview
This is a complete, self-contained Windows print service for Quality Label system with zero external dependencies.
## 📦 Package Contents
### Core Files:
- `print_service_complete.py` - Main Python service (uses only standard library)
- `install_service_complete.bat` - Complete installer (run as Administrator)
- `uninstall_service_complete.bat` - Complete uninstaller
- `requirements_complete.txt` - Dependencies list (all standard library)
### Chrome Extension:
- `chrome_extension/` - Complete Chrome extension for web integration
- `chrome_extension/manifest.json` - Extension configuration
- `chrome_extension/background.js` - Service communication
- `chrome_extension/popup.html` - Extension interface
### Documentation:
- `README.md` - This file
- `PORTABLE_PYTHON_INSTRUCTIONS.txt` - Guide for Python distribution
- `INSTALLATION_COMPLETE.md` - Detailed installation guide
### Optional Build Tools:
- `build_executable.bat` - Creates standalone .exe (requires PyInstaller)
- `build_package.py` - Package builder script
## 🚀 Quick Installation (5 Minutes)
### Prerequisites:
- Windows 10/11 or Windows Server 2016+
- Administrator privileges
- Python 3.7+ (or use included portable Python)
- Google Chrome browser
### Steps:
1. **Extract Package**: Extract all files to a temporary location
2. **Run Installer**: Right-click `install_service_complete.bat` → "Run as administrator"
3. **Install Extension**: Load `chrome_extension` folder in Chrome (chrome://extensions/)
4. **Test Service**: Visit http://localhost:8765/health
## 🔧 Technical Details
### Service Architecture:
```
Web App → Chrome Extension → Windows Service → Printer
```
### Features:
- ✅ Pure Python implementation (standard library only)
- ✅ Multiple printing methods (Adobe Reader, SumatraPDF, PowerShell, Edge, System Default)
- ✅ Automatic service recovery and restart
- ✅ Comprehensive logging system
- ✅ Cross-printer compatibility
- ✅ Zero external dependencies
- ✅ Windows service integration
- ✅ Chrome extension communication
### Service Endpoints:
- `GET /health` - Service health check
- `GET /printers` - List available printers
- `GET /status` - Service status and statistics
- `POST /print_pdf` - Print PDF file
### Printing Methods (Fallback Chain):
1. Adobe Reader command line
2. SumatraPDF automation
3. PowerShell printing
4. Microsoft Edge integration
5. System default application
## 🛠️ Advanced Configuration
### Service Configuration:
- Service Name: `QualityPrintService`
- Display Name: `Quality Label Print Service`
- Installation Path: `C:\QualityPrintService\`
- Log Directory: `%USERPROFILE%\PrintService\logs\`
- Port: `8765` (localhost only)
### Logging:
- Daily log rotation
- Separate error and output logs
- Configurable log levels
- Automatic cleanup
### Recovery Options:
- Auto-restart on failure (3 attempts)
- 5-second delay between restarts
- 24-hour reset period
- Scheduled task fallback
## 🐛 Troubleshooting
### Service Won't Start:
1. Check Windows Event Viewer
2. Verify Python installation
3. Check port 8765 availability
4. Run as Administrator
### Printing Issues:
1. Verify printer installation
2. Check printer permissions
3. Test with different print methods
4. Review service logs
### Extension Issues:
1. Reload extension in Chrome
2. Check extension permissions
3. Verify service connectivity
4. Clear browser cache
### Common Solutions:
```bash
# Check service status
sc query QualityPrintService
# Restart service
sc stop QualityPrintService
sc start QualityPrintService
# Test connectivity
curl http://localhost:8765/health
# View logs
type "%USERPROFILE%\PrintService\logs\print_service_*.log"
```
## 📋 System Requirements
### Minimum Requirements:
- Windows 10 (1903) or Windows Server 2016
- 50 MB free disk space
- Python 3.7+ (can be portable)
- Chrome/Edge browser
- Local printer access
### Recommended:
- Windows 10/11 (latest)
- 100 MB free disk space
- Python 3.9+
- Administrative privileges
- Network printer access
## 🔒 Security Notes
- Service runs on localhost only (127.0.0.1:8765)
- No external network access required
- Uses Windows authentication
- Temporary files auto-cleanup
- Secure PDF handling
## 🚀 Performance
- Memory usage: ~15-30 MB
- CPU usage: <1% (idle)
- Startup time: ~2 seconds
- Print processing: ~1-3 seconds per job
## 📞 Support
For issues or questions:
1. Check this README
2. Review log files
3. Test with different browsers
4. Verify printer connectivity
## 📝 License
Internal use only - Quality Label System

View File

@@ -1,165 +0,0 @@
# Windows Print Service - Error 1053 Troubleshooting Guide
## 🚨 Windows Service Error 1053 - "Service did not respond to start or control request"
This error occurs when Windows services don't communicate properly with the Service Control Manager (SCM). Here's how to fix it:
### 🔧 SOLUTION 1: Use the Enhanced Service Package
**Problem**: The original service wasn't designed for Windows service requirements.
**Fix**: Updated service architecture with proper Windows service communication.
#### New Files Included:
-`service_wrapper.py` - Handles Windows service communication
-`print_service_complete.py` - Enhanced with signal handling and proper shutdown
-`test_service.bat` - Test service in standalone mode before installing
### 🧪 STEP-BY-STEP TROUBLESHOOTING:
#### Step 1: Test Service in Standalone Mode
```cmd
# Run this to test the service before installing as Windows service
test_service.bat
```
If this works, the service code is fine. If not, check the logs.
#### Step 2: Check Python and Dependencies
```cmd
# Verify Python embedded is working
cd C:\QualityPrintService\python_embedded
python.exe --version
# Test the service script directly
python.exe ..\print_service_complete.py --test
```
#### Step 3: Install with Enhanced Wrapper
The installer now creates a service wrapper that properly communicates with Windows SCM:
```cmd
# Uninstall old service
sc stop QualityPrintService
sc delete QualityPrintService
# Reinstall with enhanced wrapper
install_service_complete.bat
```
#### Step 4: Manual Service Control
```cmd
# Start service manually to see error details
net start QualityPrintService
# Check service status
sc query QualityPrintService
# View service logs
type "%USERPROFILE%\PrintService\logs\service_wrapper_*.log"
```
### 🔍 DIAGNOSTIC COMMANDS:
#### Check Service Installation:
```cmd
sc query QualityPrintService
sc qc QualityPrintService
```
#### Check Port Availability:
```cmd
netstat -an | findstr :8765
```
#### Test HTTP Endpoints:
```cmd
curl http://localhost:8765/health
# OR
powershell Invoke-WebRequest -Uri "http://localhost:8765/health"
```
### 📋 COMMON SOLUTIONS:
#### Solution A: Port Already in Use
```cmd
# Find process using port 8765
netstat -ano | findstr :8765
# Kill process if needed (replace PID)
taskkill /PID <PID_NUMBER> /F
```
#### Solution B: Python Path Issues
```cmd
# Verify Python embedded path in service wrapper
type "C:\QualityPrintService\service_wrapper.bat"
```
#### Solution C: Permissions Issues
```cmd
# Run installer as Administrator
# Right-click install_service_complete.bat → "Run as administrator"
```
#### Solution D: Service Recovery
```cmd
# Configure automatic recovery
sc failure QualityPrintService reset= 86400 actions= restart/5000/restart/5000/restart/5000
```
### 📊 SERVICE STATUS VERIFICATION:
#### Successful Service Start:
- Service Status: RUNNING
- HTTP Response: `{"status": "healthy", "service": "Windows Print Service"}`
- Log Shows: "Service is ready and listening..."
#### Failed Service Start:
- Service Status: STOPPED or START_PENDING
- HTTP Response: Connection refused
- Log Shows: Error messages with specific details
### 🛠️ ADVANCED TROUBLESHOOTING:
#### Enable Debug Logging:
Edit the service script to increase logging level:
```python
logging.basicConfig(level=logging.DEBUG)
```
#### Manual Service Wrapper Test:
```cmd
cd C:\QualityPrintService
python_embedded\python.exe service_wrapper.py
```
#### Windows Event Viewer:
1. Open Event Viewer
2. Navigate: Windows Logs → Application
3. Filter by Source: Service Control Manager
4. Look for QualityPrintService errors
### 📞 SUPPORT CHECKLIST:
Before reporting issues, please verify:
- [ ] ✅ Python embedded is working (`python_embedded\python.exe --version`)
- [ ] ✅ Service runs in standalone mode (`test_service.bat`)
- [ ] ✅ Port 8765 is available (`netstat -an | findstr :8765`)
- [ ] ✅ Installer was run as Administrator
- [ ] ✅ Windows is Windows 10/11 or Server 2016+
- [ ] ✅ Service logs show specific error messages
### 🎯 EXPECTED RESULTS:
After following this guide:
1. **Service Status**: RUNNING
2. **Health Check**: http://localhost:8765/health returns JSON response
3. **Chrome Extension**: Detects service and shows "Windows Service" mode
4. **Printing**: Silent PDF printing works without dialogs
---
**Package Version**: Zero Dependencies Complete
**Last Updated**: September 2025
**Support**: Check service logs in `%USERPROFILE%\PrintService\logs\`

View File

@@ -1,26 +0,0 @@
@echo off
echo Building standalone Windows Print Service executable...
REM Check if PyInstaller is available
pip show pyinstaller >nul 2>&1
if %errorLevel% neq 0 (
echo Installing PyInstaller...
pip install pyinstaller
)
REM Build standalone executable
echo Creating standalone executable...
pyinstaller --onefile --noconsole --name="QualityPrintService" print_service_complete.py
if %errorLevel% equ 0 (
echo.
echo ✓ Executable created successfully!
echo Location: dist\QualityPrintService.exe
echo.
echo You can now distribute the .exe file instead of the Python script
echo Update install_service_complete.bat to use the .exe file
) else (
echo ERROR: Failed to create executable
)
pause

View File

@@ -1,586 +0,0 @@
#!/usr/bin/env python3
"""
Build script to create a complete self-contained Windows Print Service package
This script prepares all dependencies and creates the distribution package
"""
import os
import shutil
import zipfile
import sys
import subprocess
import tempfile
from pathlib import Path
def create_portable_python_package():
"""Create instructions for portable Python package."""
instructions = """
# PORTABLE PYTHON PACKAGE INSTRUCTIONS
To create a complete self-contained package, you need to include a portable Python interpreter.
## Option 1: Download Embedded Python (Recommended)
1. Download Python 3.11 Embedded from: https://www.python.org/downloads/windows/
2. Choose "Windows embeddable package (64-bit)" or "(32-bit)"
3. Extract to a folder named 'python_portable'
4. The structure should be:
python_portable/
├── python.exe
├── python311.dll (or similar)
├── pythoncom311.dll
└── ... (other Python files)
## Option 2: Use PyInstaller (Alternative)
1. Install PyInstaller: pip install pyinstaller
2. Run: pyinstaller --onefile --noconsole print_service_complete.py
3. This creates a single .exe file with all dependencies
## Option 3: Manual Python Installation Check
The installer will check for system Python and use it if available.
## Current Package Structure
This package includes:
✓ Complete Python script with all dependencies
✓ Windows service installer
✓ Chrome extension
✓ Logging and error handling
✓ Multiple printing method fallbacks
✓ Automatic recovery options
## Dependencies Included in Python Script:
- All standard library modules (http.server, json, subprocess, etc.)
- No external dependencies required
- Pure Python implementation
The service will work with any Python 3.7+ installation.
"""
with open('PORTABLE_PYTHON_INSTRUCTIONS.txt', 'w') as f:
f.write(instructions)
print("✓ Created portable Python instructions")
def create_build_executable_script():
"""Create script to build standalone executable."""
build_script = """@echo off
echo Building standalone Windows Print Service executable...
REM Check if PyInstaller is available
pip show pyinstaller >nul 2>&1
if %errorLevel% neq 0 (
echo Installing PyInstaller...
pip install pyinstaller
)
REM Build standalone executable
echo Creating standalone executable...
pyinstaller --onefile --noconsole --name="QualityPrintService" print_service_complete.py
if %errorLevel% equ 0 (
echo.
echo ✓ Executable created successfully!
echo Location: dist\\QualityPrintService.exe
echo.
echo You can now distribute the .exe file instead of the Python script
echo Update install_service_complete.bat to use the .exe file
) else (
echo ERROR: Failed to create executable
)
pause
"""
with open('build_executable.bat', 'w') as f:
f.write(build_script)
print("✓ Created executable build script")
def create_complete_readme():
"""Create comprehensive README for the package."""
readme_content = """# Quality Windows Print Service - Complete Self-Contained Package
## 🎯 Overview
This is a complete, self-contained Windows print service for Quality Label system with zero external dependencies.
## 📦 Package Contents
### Core Files:
- `print_service_complete.py` - Main Python service (uses only standard library)
- `install_service_complete.bat` - Complete installer (run as Administrator)
- `uninstall_service_complete.bat` - Complete uninstaller
- `requirements_complete.txt` - Dependencies list (all standard library)
### Chrome Extension:
- `chrome_extension/` - Complete Chrome extension for web integration
- `chrome_extension/manifest.json` - Extension configuration
- `chrome_extension/background.js` - Service communication
- `chrome_extension/popup.html` - Extension interface
### Documentation:
- `README.md` - This file
- `PORTABLE_PYTHON_INSTRUCTIONS.txt` - Guide for Python distribution
- `INSTALLATION_COMPLETE.md` - Detailed installation guide
### Optional Build Tools:
- `build_executable.bat` - Creates standalone .exe (requires PyInstaller)
- `build_package.py` - Package builder script
## 🚀 Quick Installation (5 Minutes)
### Prerequisites:
- Windows 10/11 or Windows Server 2016+
- Administrator privileges
- Python 3.7+ (or use included portable Python)
- Google Chrome browser
### Steps:
1. **Extract Package**: Extract all files to a temporary location
2. **Run Installer**: Right-click `install_service_complete.bat` → "Run as administrator"
3. **Install Extension**: Load `chrome_extension` folder in Chrome (chrome://extensions/)
4. **Test Service**: Visit http://localhost:8765/health
## 🔧 Technical Details
### Service Architecture:
```
Web App → Chrome Extension → Windows Service → Printer
```
### Features:
- ✅ Pure Python implementation (standard library only)
- ✅ Multiple printing methods (Adobe Reader, SumatraPDF, PowerShell, Edge, System Default)
- ✅ Automatic service recovery and restart
- ✅ Comprehensive logging system
- ✅ Cross-printer compatibility
- ✅ Zero external dependencies
- ✅ Windows service integration
- ✅ Chrome extension communication
### Service Endpoints:
- `GET /health` - Service health check
- `GET /printers` - List available printers
- `GET /status` - Service status and statistics
- `POST /print_pdf` - Print PDF file
### Printing Methods (Fallback Chain):
1. Adobe Reader command line
2. SumatraPDF automation
3. PowerShell printing
4. Microsoft Edge integration
5. System default application
## 🛠️ Advanced Configuration
### Service Configuration:
- Service Name: `QualityPrintService`
- Display Name: `Quality Label Print Service`
- Installation Path: `C:\\QualityPrintService\\`
- Log Directory: `%USERPROFILE%\\PrintService\\logs\\`
- Port: `8765` (localhost only)
### Logging:
- Daily log rotation
- Separate error and output logs
- Configurable log levels
- Automatic cleanup
### Recovery Options:
- Auto-restart on failure (3 attempts)
- 5-second delay between restarts
- 24-hour reset period
- Scheduled task fallback
## 🐛 Troubleshooting
### Service Won't Start:
1. Check Windows Event Viewer
2. Verify Python installation
3. Check port 8765 availability
4. Run as Administrator
### Printing Issues:
1. Verify printer installation
2. Check printer permissions
3. Test with different print methods
4. Review service logs
### Extension Issues:
1. Reload extension in Chrome
2. Check extension permissions
3. Verify service connectivity
4. Clear browser cache
### Common Solutions:
```bash
# Check service status
sc query QualityPrintService
# Restart service
sc stop QualityPrintService
sc start QualityPrintService
# Test connectivity
curl http://localhost:8765/health
# View logs
type "%USERPROFILE%\\PrintService\\logs\\print_service_*.log"
```
## 📋 System Requirements
### Minimum Requirements:
- Windows 10 (1903) or Windows Server 2016
- 50 MB free disk space
- Python 3.7+ (can be portable)
- Chrome/Edge browser
- Local printer access
### Recommended:
- Windows 10/11 (latest)
- 100 MB free disk space
- Python 3.9+
- Administrative privileges
- Network printer access
## 🔒 Security Notes
- Service runs on localhost only (127.0.0.1:8765)
- No external network access required
- Uses Windows authentication
- Temporary files auto-cleanup
- Secure PDF handling
## 🚀 Performance
- Memory usage: ~15-30 MB
- CPU usage: <1% (idle)
- Startup time: ~2 seconds
- Print processing: ~1-3 seconds per job
## 📞 Support
For issues or questions:
1. Check this README
2. Review log files
3. Test with different browsers
4. Verify printer connectivity
## 📝 License
Internal use only - Quality Label System
"""
with open('README_COMPLETE.md', 'w') as f:
f.write(readme_content)
print("✓ Created comprehensive README")
def create_installation_guide():
"""Create detailed installation guide."""
guide_content = """# Quality Print Service - Complete Installation Guide
## 🎯 Pre-Installation Checklist
### System Requirements Verification:
- [ ] Windows 10 build 1903+ or Windows Server 2016+
- [ ] Administrator access to the system
- [ ] Google Chrome browser installed
- [ ] At least 100 MB free disk space
- [ ] Network/USB printer connected and configured
### Python Requirements:
- [ ] Python 3.7+ installed OR use included portable Python
- [ ] Python accessible via command line (optional)
## 📦 Installation Methods
### Method 1: Complete Automatic Installation (Recommended)
1. **Download and Extract**:
- Extract the complete package to any folder (e.g., Desktop)
- No need to keep the files permanently
2. **Run Installer**:
```
Right-click: install_service_complete.bat
Select: "Run as administrator"
```
3. **Follow Installation Steps**:
```
[1/6] Administrator privileges confirmed ✓
[2/6] Checking Python installation...
[3/6] Creating installation directories...
[4/6] Installing service files...
[5/6] Installing Windows service...
[6/6] Starting service...
```
4. **Install Chrome Extension**:
- Chrome will open the extension folder automatically
- Go to `chrome://extensions/`
- Enable "Developer mode" (top right)
- Click "Load unpacked"
- Select the `chrome_extension` folder
5. **Verify Installation**:
- Visit: `http://localhost:8765/health`
- Expected response: `{"status": "healthy"}`
### Method 2: Manual Installation
1. **Create Directories**:
```cmd
mkdir C:\QualityPrintService
mkdir %USERPROFILE%\PrintService\logs
```
2. **Copy Files**:
```cmd
copy print_service_complete.py C:\QualityPrintService\
```
3. **Install Service**:
```cmd
sc create QualityPrintService binPath="python C:\QualityPrintService\print_service_complete.py"
sc start QualityPrintService
```
## 🔧 Post-Installation Configuration
### Service Verification:
```cmd
# Check service status
sc query QualityPrintService
# Check service configuration
sc qc QualityPrintService
# View service logs (if using NSSM)
type "%USERPROFILE%\PrintService\logs\service_output.log"
```
### Network Testing:
```powershell
# Test health endpoint
Invoke-RestMethod -Uri http://localhost:8765/health
# Test printer endpoint
Invoke-RestMethod -Uri http://localhost:8765/printers
# Test from browser
start http://localhost:8765/status
```
### Chrome Extension Setup:
1. Open Chrome browser
2. Navigate to `chrome://extensions/`
3. Enable "Developer mode" toggle (top-right corner)
4. Click "Load unpacked" button
5. Browse and select the `chrome_extension` folder
6. Verify extension appears in the list with green toggle
## 🔍 Installation Verification
### Health Check Procedure:
1. **Service Status**: Verify Windows service is running
```cmd
sc query QualityPrintService | find "RUNNING"
```
2. **Network Connectivity**: Test HTTP endpoints
```cmd
curl http://localhost:8765/health
```
3. **Printer Detection**: Check printer enumeration
```cmd
curl http://localhost:8765/printers
```
4. **Extension Communication**: Test from web page
- Open the Quality app in Chrome
- Go to print module
- Verify "Extension ready" status
### Expected Responses:
**Health Check**:
```json
{
"status": "healthy",
"service": "Windows Print Service",
"version": "1.0.0",
"timestamp": "2025-09-25T10:30:00"
}
```
**Printer List**:
```json
{
"success": true,
"printers": [
{"name": "HP LaserJet", "type": "Local", "status": "Available"}
],
"count": 1
}
```
## 🚨 Troubleshooting Common Issues
### Issue: "Administrator privileges required"
**Solution**:
- Right-click installer file
- Select "Run as administrator"
- Confirm UAC prompt
### Issue: "Python not found"
**Solutions**:
1. Install Python from python.org
2. Use included portable Python
3. Add Python to system PATH
### Issue: "Service failed to start"
**Solutions**:
1. Check Windows Event Viewer:
- Windows Logs → Application
- Filter by source: "Service Control Manager"
2. Verify port 8765 is not in use:
```cmd
netstat -an | find "8765"
```
3. Check service logs:
```cmd
type "%USERPROFILE%\PrintService\logs\print_service_*.log"
```
### Issue: "Chrome extension not working"
**Solutions**:
1. Reload extension in `chrome://extensions/`
2. Check extension permissions
3. Verify service is responding at `localhost:8765`
4. Clear browser cache and cookies
### Issue: "PDF printing fails"
**Solutions**:
1. Install Adobe Reader or SumatraPDF
2. Check printer permissions
3. Verify PDF file accessibility
4. Test with different printer
## 🔄 Maintenance and Updates
### Regular Maintenance:
- **Log Cleanup**: Logs rotate automatically
- **Service Monitoring**: Check service status weekly
- **Chrome Extension**: Update when prompted
### Manual Service Management:
```cmd
# Stop service
sc stop QualityPrintService
# Start service
sc start QualityPrintService
# Restart service
sc stop QualityPrintService && timeout /t 3 && sc start QualityPrintService
# Change startup type
sc config QualityPrintService start= auto
```
### Log File Locations:
- Service logs: `%USERPROFILE%\PrintService\logs\`
- Windows Event Logs: Event Viewer → Windows Logs → Application
- Chrome Extension: Chrome DevTools → Console
## 🔧 Advanced Configuration
### Custom Port Configuration:
Edit `print_service_complete.py`:
```python
server_address = ('localhost', 8765) # Change 8765 to desired port
```
### Custom Install Directory:
Edit `install_service_complete.bat`:
```batch
set INSTALL_DIR=C:\CustomPath\PrintService
```
### Service Recovery Options:
```cmd
sc failure QualityPrintService reset= 86400 actions= restart/5000/restart/10000/restart/30000
```
## 📋 Uninstallation
### Complete Removal:
1. Run `uninstall_service_complete.bat` as Administrator
2. Remove Chrome extension manually
3. Optional: Delete log files
### Manual Removal:
```cmd
# Stop and remove service
sc stop QualityPrintService
sc delete QualityPrintService
# Remove files
rmdir /s /q C:\QualityPrintService
rmdir /s /q "%USERPROFILE%\PrintService"
```
## 📞 Getting Help
### Before Contacting Support:
1. Check this installation guide
2. Review troubleshooting section
3. Check service logs for error messages
4. Test with simple printer (like Microsoft Print to PDF)
### Information to Provide:
- Windows version (run `winver`)
- Python version (run `python --version`)
- Service status (run `sc query QualityPrintService`)
- Recent log entries
- Error messages or screenshots
---
**Installation Guide Version**: 1.0.0
**Last Updated**: September 2025
**Support**: Internal Quality System Team
"""
with open('INSTALLATION_COMPLETE.md', 'w') as f:
f.write(guide_content)
print("✓ Created detailed installation guide")
def build_complete_package():
"""Build the complete package with all dependencies."""
print("Building complete Windows Print Service package...")
# Create documentation files
create_portable_python_package()
create_build_executable_script()
create_complete_readme()
create_installation_guide()
print("\n✓ Complete package prepared!")
print("\nFiles created:")
print(" ✓ print_service_complete.py - Main service with all dependencies")
print(" ✓ install_service_complete.bat - Complete installer")
print(" ✓ uninstall_service_complete.bat - Complete uninstaller")
print(" ✓ requirements_complete.txt - Dependencies list")
print(" ✓ README_COMPLETE.md - Comprehensive documentation")
print(" ✓ INSTALLATION_COMPLETE.md - Detailed installation guide")
print(" ✓ PORTABLE_PYTHON_INSTRUCTIONS.txt - Python distribution guide")
print(" ✓ build_executable.bat - Executable builder")
print("\nNext steps:")
print("1. Include a portable Python distribution (see PORTABLE_PYTHON_INSTRUCTIONS.txt)")
print("2. Test the complete package on a clean Windows system")
print("3. Package everything into the download ZIP")
return True
if __name__ == "__main__":
build_complete_package()

View File

@@ -1,307 +0,0 @@
/**
* Quality Label Printing Extension - Windows Service Communication
* Communicates with local Windows print service for silent printing
*/
console.log('Quality Label Printing Extension - Windows Service Mode');
// Service configuration
const PRINT_SERVICE_URL = 'http://localhost:8765';
const SERVICE_TIMEOUT = 30000; // 30 seconds
// Initialize extension
chrome.runtime.onInstalled.addListener(() => {
console.log('Quality Label Printing Service extension installed - Windows Service Mode');
testServiceConnection();
});
// Test connection to Windows service
async function testServiceConnection() {
try {
const response = await fetch(`${PRINT_SERVICE_URL}/health`, {
method: 'GET',
timeout: 5000
});
if (response.ok) {
const data = await response.json();
console.log('✅ Windows Print Service connected:', data);
return true;
} else {
console.warn('⚠️ Windows Print Service not responding:', response.status);
return false;
}
} catch (error) {
console.warn('❌ Windows Print Service not available:', error.message);
return false;
}
}
// Handle messages from content scripts or web pages
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log('Background script received message:', message);
switch (message.action) {
case 'print_pdf':
handleWindowsServicePrint(message)
.then(result => {
console.log('Windows service print completed:', result);
sendResponse(result);
})
.catch(error => {
console.error('Windows service print error:', error);
sendResponse({ success: false, error: error.message });
});
return true; // Keep message channel open for async response
case 'get_printers':
getAvailablePrinters()
.then(printers => {
sendResponse({ success: true, printers: printers });
})
.catch(error => {
console.error('Error getting printers:', error);
sendResponse({
success: false,
error: error.message,
printers: [{ name: 'default', display_name: 'Default Printer', is_default: true }]
});
});
return true;
case 'ping':
testServiceConnection()
.then(connected => {
sendResponse({
success: true,
extension_version: chrome.runtime.getManifest().version,
ready: true,
service_connected: connected,
mode: 'windows_service'
});
})
.catch(() => {
sendResponse({
success: true,
extension_version: chrome.runtime.getManifest().version,
ready: false,
service_connected: false,
mode: 'windows_service'
});
});
return true;
default:
sendResponse({ error: 'Unknown action', success: false });
}
});
// Handle external messages from web pages
chrome.runtime.onMessageExternal.addListener((message, sender, sendResponse) => {
console.log('External message received:', message, 'from:', sender);
// Verify sender origin for security
const allowedOrigins = [
'http://localhost:5000',
'http://localhost:8000',
'http://127.0.0.1:5000',
'http://127.0.0.1:8000',
'http://localhost:3000',
'http://localhost:8080'
];
if (!allowedOrigins.some(origin => sender.url && sender.url.startsWith(origin))) {
console.warn('Unauthorized origin:', sender.url);
sendResponse({ error: 'Unauthorized origin', success: false });
return;
}
// Handle the message
switch (message.action) {
case 'print_pdf':
handleWindowsServicePrint(message)
.then(result => sendResponse(result))
.catch(error => {
console.error('Print PDF error:', error);
sendResponse({ success: false, error: error.message });
});
return true;
case 'ping':
testServiceConnection()
.then(connected => {
sendResponse({
success: true,
extension_version: chrome.runtime.getManifest().version,
ready: true,
service_connected: connected,
mode: 'windows_service'
});
})
.catch(() => {
sendResponse({
success: true,
extension_version: chrome.runtime.getManifest().version,
ready: false,
service_connected: false,
mode: 'windows_service'
});
});
return true;
default:
sendResponse({ error: 'Unknown action', success: false });
}
});
/**
* Get available printers from Windows service
*/
async function getAvailablePrinters() {
try {
const response = await fetch(`${PRINT_SERVICE_URL}/printers`, {
method: 'GET',
timeout: 10000
});
if (response.ok) {
const data = await response.json();
return data.printers || [];
} else {
throw new Error(`Service responded with status: ${response.status}`);
}
} catch (error) {
console.error('Failed to get printers from service:', error);
throw error;
}
}
/**
* Handle PDF printing via Windows Service
*/
async function handleWindowsServicePrint(message) {
console.log('🖨️ Sending PDF to Windows print service:', message);
try {
const { pdfUrl, orderId, prodOrder, quantity, printerName } = message;
if (!pdfUrl) {
throw new Error('PDF URL is required');
}
// First, test if service is available
const serviceAvailable = await testServiceConnection();
if (!serviceAvailable) {
throw new Error('Windows Print Service is not running. Please ensure the service is installed and started.');
}
// Prepare print request
const printRequest = {
pdf_url: pdfUrl,
printer_name: printerName || 'default',
order_id: orderId,
prod_order: prodOrder,
quantity: quantity,
timestamp: new Date().toISOString()
};
console.log('📤 Sending print request to service:', printRequest);
// Send PDF to Windows service for printing
const response = await fetch(`${PRINT_SERVICE_URL}/print_pdf`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(printRequest)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Print service error (${response.status}): ${errorText}`);
}
const result = await response.json();
if (result.success) {
console.log('✅ Print job sent successfully:', result);
return {
success: true,
message: `PDF sent to ${result.printer || printerName || 'default printer'} successfully`,
method: result.method || 'Windows Print Service',
printer: result.printer || printerName,
orderId: orderId,
instruction: 'PDF has been sent to the printer queue'
};
} else {
throw new Error(result.error || 'Unknown print service error');
}
} catch (error) {
console.error('❌ Windows service print failed:', error);
// Fallback: Return instruction to print manually
return {
success: false,
error: error.message,
fallback: true,
instruction: 'Windows service unavailable. Please download and print the PDF manually.'
};
}
}
/**
* Fallback function for when Windows service is not available
*/
async function handleFallbackPrint(message) {
console.log('🔄 Using fallback print method:', message);
try {
const { pdfUrl, orderId, prodOrder, quantity } = message;
// Create a new tab with the PDF
const tab = await chrome.tabs.create({
url: pdfUrl,
active: false // Don't switch to the tab
});
// Wait a moment for PDF to load
await new Promise(resolve => setTimeout(resolve, 2000));
// Get the created tab
const updatedTab = await chrome.tabs.get(tab.id);
return {
success: true,
message: `PDF opened in new tab for manual printing`,
method: 'Manual Print Fallback',
tabId: tab.id,
instruction: 'PDF opened in new tab. Use Ctrl+P to print or close the tab if not needed.'
};
} catch (error) {
console.error('❌ Fallback print failed:', error);
throw error;
}
}
// Utility functions
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Extension startup
console.log('🖨️ Quality Label Printing Extension loaded - Windows Service Mode');
console.log(`🔗 Service URL: ${PRINT_SERVICE_URL}`);
// Test service on startup
testServiceConnection().then(connected => {
if (connected) {
console.log('✅ Windows Print Service is available');
} else {
console.log('⚠️ Windows Print Service is not available - fallback mode active');
}
});
console.log('✅ Background script loaded successfully - Platform safe mode enabled');

View File

@@ -1,48 +0,0 @@
/**
* Quality Label Printing Service - Content Script
* Simplified injection for extension ID detection
*/
console.log('Quality Label Printing - Content Script Loaded');
// Inject extension ID into DOM for web page detection
function injectExtensionId() {
// Remove any existing extension ID element
const existingElement = document.getElementById('chrome-extension-id');
if (existingElement) {
existingElement.remove();
}
// Create new element with extension ID
const extensionIdElement = document.createElement('div');
extensionIdElement.id = 'chrome-extension-id';
extensionIdElement.setAttribute('data-extension-id', chrome.runtime.id);
extensionIdElement.style.display = 'none';
// Add to document head or body
(document.head || document.body || document.documentElement).appendChild(extensionIdElement);
console.log('Extension ID injected:', chrome.runtime.id);
}
// Inject extension ID when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', injectExtensionId);
} else {
injectExtensionId();
}
// Also inject when page changes (for SPAs)
if (window.navigation) {
navigation.addEventListener('navigate', injectExtensionId);
} else {
// Fallback for older browsers
let lastUrl = location.href;
new MutationObserver(() => {
const url = location.href;
if (url !== lastUrl) {
lastUrl = url;
setTimeout(injectExtensionId, 100);
}
}).observe(document, { subtree: true, childList: true });
}

View File

@@ -1,7 +0,0 @@
# Placeholder for icon files - in production, add actual PNG icons:
# - icon16.png (16x16 pixels)
# - icon48.png (48x48 pixels)
# - icon128.png (128x128 pixels)
# For now, create simple text-based icons using SVG converted to PNG
# These should be replaced with proper icons later

View File

@@ -1,27 +0,0 @@
# Simple text-based icons for the Chrome extension
# These are placeholder files - replace with actual PNG icons for production
# Create simple SVG icons that can be converted to PNG
ICON_16_SVG = '''
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
<rect width="16" height="16" fill="#007bff"/>
<text x="8" y="12" font-family="Arial" font-size="10" fill="white" text-anchor="middle">🖨</text>
</svg>
'''
ICON_48_SVG = '''
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" fill="#007bff" rx="8"/>
<text x="24" y="32" font-family="Arial" font-size="24" fill="white" text-anchor="middle">🖨️</text>
</svg>
'''
ICON_128_SVG = '''
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
<rect width="128" height="128" fill="#007bff" rx="16"/>
<text x="64" y="84" font-family="Arial" font-size="48" fill="white" text-anchor="middle">🖨️</text>
</svg>
'''
# For now, create simple text placeholders
# In production, convert these SVGs to PNG files

View File

@@ -1,122 +0,0 @@
#!/usr/bin/env python3
"""
Generate PNG icons for Chrome extension
Creates simple colored squares with printer icons
"""
try:
from PIL import Image, ImageDraw, ImageFont
PIL_AVAILABLE = True
except ImportError:
PIL_AVAILABLE = False
import os
def create_simple_icon(size, filename):
"""Create a simple colored square icon"""
if PIL_AVAILABLE:
# Create image with PIL
img = Image.new('RGBA', (size, size), (0, 123, 255, 255)) # Blue background
draw = ImageDraw.Draw(img)
# Add a white border
border_width = max(1, size // 16)
draw.rectangle([0, 0, size-1, size-1], outline=(255, 255, 255, 255), width=border_width)
# Add text (P for Print)
try:
font_size = size // 2
font = ImageFont.load_default()
text = "P"
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
x = (size - text_width) // 2
y = (size - text_height) // 2
draw.text((x, y), text, fill=(255, 255, 255, 255), font=font)
except:
pass
img.save(filename, 'PNG')
print(f"Created {filename} ({size}x{size})")
else:
# Create a minimal PNG file without PIL
create_minimal_png(size, filename)
def create_minimal_png(size, filename):
"""Create a minimal PNG file without PIL"""
# This creates a very basic PNG file
# Blue square with minimal PNG structure
import struct
import zlib
# PNG signature
png_signature = b'\x89PNG\r\n\x1a\n'
# IHDR chunk
width = height = size
bit_depth = 8
color_type = 2 # RGB
compression = 0
filter_method = 0
interlace = 0
ihdr_data = struct.pack('>IIBBBBB', width, height, bit_depth, color_type, compression, filter_method, interlace)
ihdr_crc = zlib.crc32(b'IHDR' + ihdr_data) & 0xffffffff
ihdr_chunk = struct.pack('>I', len(ihdr_data)) + b'IHDR' + ihdr_data + struct.pack('>I', ihdr_crc)
# IDAT chunk (blue pixels)
pixels = []
for y in range(height):
row = [0] # Filter byte
for x in range(width):
# Blue color RGB(0, 123, 255)
row.extend([0, 123, 255])
pixels.extend(row)
pixel_data = bytes(pixels)
compressed_data = zlib.compress(pixel_data)
idat_crc = zlib.crc32(b'IDAT' + compressed_data) & 0xffffffff
idat_chunk = struct.pack('>I', len(compressed_data)) + b'IDAT' + compressed_data + struct.pack('>I', idat_crc)
# IEND chunk
iend_crc = zlib.crc32(b'IEND') & 0xffffffff
iend_chunk = struct.pack('>I', 0) + b'IEND' + struct.pack('>I', iend_crc)
# Write PNG file
with open(filename, 'wb') as f:
f.write(png_signature)
f.write(ihdr_chunk)
f.write(idat_chunk)
f.write(iend_chunk)
print(f"Created minimal {filename} ({size}x{size})")
def main():
# Create icons directory if it doesn't exist
icons_dir = "/home/ske087/quality_recticel/windows_print_service/chrome_extension/icons"
print("Creating Chrome extension icons...")
print(f"PIL available: {PIL_AVAILABLE}")
# Create required icon sizes
sizes = [16, 32, 48, 128]
for size in sizes:
filename = os.path.join(icons_dir, f"icon{size}.png")
create_simple_icon(size, filename)
print("✅ All icons created successfully!")
print("\nIcons created:")
for size in sizes:
filename = f"icon{size}.png"
filepath = os.path.join(icons_dir, filename)
if os.path.exists(filepath):
file_size = os.path.getsize(filepath)
print(f"{filename} ({size}x{size}px, {file_size} bytes)")
else:
print(f"{filename} - FAILED")
if __name__ == "__main__":
main()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 B

View File

@@ -1,4 +0,0 @@
# Placeholder for 128x128 icon
# This is a text file placeholder
# Replace with actual icon128.png file
🖨️

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

View File

@@ -1,4 +0,0 @@
# Placeholder for 16x16 icon
# This is a text file placeholder
# Replace with actual icon16.png file
🖨️

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

View File

@@ -1,4 +0,0 @@
# Placeholder for 48x48 icon
# This is a text file placeholder
# Replace with actual icon48.png file
🖨️

View File

@@ -1,61 +0,0 @@
{
"manifest_version": 3,
"name": "Quality Label Printing Service",
"version": "1.0.0",
"description": "Simple silent PDF printing for Quality Label Printing application",
"permissions": [
"activeTab",
"storage",
"downloads",
"tabs",
"scripting"
],
"host_permissions": [
"http://localhost:*/*",
"https://localhost:*/*",
"http://*/*",
"https://*/*"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_end"
}],
"action": {
"default_popup": "popup.html",
"default_title": "Quality Label Printing Service",
"default_icon": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"web_accessible_resources": [{
"resources": ["content.js"],
"matches": ["<all_urls>"]
}],
"externally_connectable": {
"matches": [
"http://localhost:*/*",
"https://localhost:*/*"
]
}
}

View File

@@ -1,196 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
width: 350px;
min-height: 200px;
margin: 0;
padding: 16px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f8f9fa;
}
.header {
text-align: center;
margin-bottom: 20px;
}
.logo {
width: 48px;
height: 48px;
margin: 0 auto 8px;
background: #007bff;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 20px;
}
.title {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 4px;
}
.version {
font-size: 12px;
color: #666;
}
.status-card {
background: white;
border-radius: 8px;
padding: 12px;
margin-bottom: 12px;
border-left: 4px solid #28a745;
}
.status-card.error {
border-left-color: #dc3545;
}
.status-card.warning {
border-left-color: #ffc107;
}
.status-title {
font-weight: 600;
font-size: 14px;
margin-bottom: 4px;
}
.status-message {
font-size: 12px;
color: #666;
margin-bottom: 8px;
}
.status-detail {
font-size: 11px;
color: #888;
}
.button {
width: 100%;
padding: 8px 12px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
margin-bottom: 8px;
transition: background-color 0.2s;
}
.button:hover {
background: #0056b3;
}
.button:disabled {
background: #6c757d;
cursor: not-allowed;
}
.button.secondary {
background: #6c757d;
}
.button.secondary:hover {
background: #545b62;
}
.printers-list {
background: white;
border-radius: 8px;
padding: 12px;
margin-top: 12px;
}
.printer-item {
padding: 8px 0;
border-bottom: 1px solid #eee;
font-size: 12px;
}
.printer-item:last-child {
border-bottom: none;
}
.printer-name {
font-weight: 600;
color: #333;
}
.printer-details {
color: #666;
font-size: 11px;
}
.footer {
text-align: center;
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid #eee;
}
.footer-link {
font-size: 11px;
color: #007bff;
text-decoration: none;
}
.loading {
text-align: center;
padding: 20px;
color: #666;
}
.hidden {
display: none;
}
</style>
</head>
<body>
<div class="header">
<div class="logo">QR</div>
<div class="title">Quality Label Printing Service</div>
<div class="version">Version 1.0.0</div>
</div>
<div id="loading" class="loading">
<div>Checking service status...</div>
</div>
<div id="content" class="hidden">
<div id="service-status" class="status-card">
<div class="status-title">Print Service Status</div>
<div class="status-message" id="status-message">Checking...</div>
<div class="status-detail" id="status-detail"></div>
</div>
<button id="refresh-btn" class="button">Refresh Status</button>
<button id="test-print-btn" class="button">Test Print</button>
<button id="get-printers-btn" class="button secondary">Get Printers</button>
<div id="printers-container" class="hidden">
<div class="printers-list">
<div style="font-weight: 600; margin-bottom: 8px; font-size: 14px;">Available Printers</div>
<div id="printers-list"></div>
</div>
</div>
</div>
<div class="footer">
<a href="#" id="help-link" class="footer-link">Help & Documentation</a>
</div>
<script src="popup.js"></script>
</body>
</html>

View File

@@ -1,261 +0,0 @@
/**
* Quality Label Printing Service - Popup Script
* Manages the extension popup interface
*/
document.addEventListener('DOMContentLoaded', async () => {
console.log('Popup loaded');
// Get elements
const elements = {
loading: document.getElementById('loading'),
content: document.getElementById('content'),
serviceStatus: document.getElementById('service-status'),
statusMessage: document.getElementById('status-message'),
statusDetail: document.getElementById('status-detail'),
refreshBtn: document.getElementById('refresh-btn'),
testPrintBtn: document.getElementById('test-print-btn'),
getPrintersBtn: document.getElementById('get-printers-btn'),
printersContainer: document.getElementById('printers-container'),
printersList: document.getElementById('printers-list'),
helpLink: document.getElementById('help-link')
};
// Initialize popup
await initializePopup();
// Event listeners
elements.refreshBtn.addEventListener('click', checkServiceStatus);
elements.testPrintBtn.addEventListener('click', testPrint);
elements.getPrintersBtn.addEventListener('click', getPrinters);
elements.helpLink.addEventListener('click', showHelp);
/**
* Initialize popup
*/
async function initializePopup() {
try {
await checkServiceStatus();
// Show content, hide loading
elements.loading.classList.add('hidden');
elements.content.classList.remove('hidden');
} catch (error) {
console.error('Initialization error:', error);
showError('Failed to initialize popup');
}
}
/**
* Check service status
*/
async function checkServiceStatus() {
try {
elements.refreshBtn.disabled = true;
elements.refreshBtn.textContent = 'Checking...';
// Send message to background script
const result = await new Promise((resolve) => {
chrome.runtime.sendMessage({ action: 'check_service' }, resolve);
});
updateServiceStatus(result);
} catch (error) {
console.error('Service check error:', error);
showError('Failed to check service status');
} finally {
elements.refreshBtn.disabled = false;
elements.refreshBtn.textContent = 'Refresh Status';
}
}
/**
* Update service status display
*/
function updateServiceStatus(result) {
const statusCard = elements.serviceStatus;
const message = elements.statusMessage;
const detail = elements.statusDetail;
if (result && result.success) {
// Service is available
statusCard.className = 'status-card';
message.textContent = 'Service is running normally';
detail.textContent = `Last checked: ${new Date().toLocaleTimeString()}`;
// Enable buttons
elements.testPrintBtn.disabled = false;
elements.getPrintersBtn.disabled = false;
} else {
// Service is not available
statusCard.className = 'status-card error';
message.textContent = 'Service is not available';
detail.textContent = result ? result.error : 'Unknown error';
// Disable buttons
elements.testPrintBtn.disabled = true;
elements.getPrintersBtn.disabled = false; // Keep enabled for diagnostics
}
}
/**
* Test print functionality
*/
async function testPrint() {
try {
elements.testPrintBtn.disabled = true;
elements.testPrintBtn.textContent = 'Testing...';
// Create test PDF data
const testPrintData = {
pdf_url: 'data:application/pdf;base64,JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKFRlc3QgUGFnZSkKL0NyZWF0b3IgKFF1YWxpdHkgUmVjdGljZWwgUHJpbnQgU2VydmljZSkKL1Byb2R1Y2VyIChRdWFsaXR5IFJlY3RpY2VsKQovQ3JlYXRpb25EYXRlIChEOjIwMjMwMTAxMTIwMDAwKQo+PgplbmRvYmoKMiAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMyAwIFIKPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1R5cGUgL1BhZ2VzCi9LaWRzIFs0IDAgUl0KL0NvdW50IDEKPJ4KZW5kb2JqCjQgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCAzIDAgUgovTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQovQ29udGVudHMgNSAwIFIKL1Jlc291cmNlcyA8PAovRm9udCA8PAovRjEgNiAwIFIKPj4KPj4KPj4KZW5kb2JqCjUgMCBvYmoKPDwKL0xlbmd0aCA0NAo+PgpzdHJlYW0KQlQKL0YxIDEyIFRmCjEwMCA3MDAgVGQKKFRlc3QgUHJpbnQgUGFnZSkgVGoKRVQKZW5kc3RyZWFtCmVuZG9iago2IDAgb2JqCjw8Ci9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMQovQmFzZUZvbnQgL0hlbHZldGljYQo+PgplbmRvYmoKeHJlZgowIDcKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAxNDggMDAwMDAgbiAKMDAwMDAwMDE5NSAwMDAwMCBuIAowMDAwMDAwMjUyIDAwMDAwIG4gCjAwMDAwMDA0MTQgMDAwMDAgbiAKMDAwMDAwMDUwOCAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDcKL1Jvb3QgMiAwIFIKL0luZm8gMSAwIFIKPj4Kc3RhcnR4cmVmCjU2NQolJUVPRgo=',
printer_name: 'default',
copies: 1
};
// Send test print request
const result = await new Promise((resolve) => {
chrome.runtime.sendMessage({
action: 'print_pdf',
data: testPrintData
}, resolve);
});
if (result && result.success) {
showSuccess('Test print sent successfully');
} else {
showError(result ? result.error : 'Test print failed');
}
} catch (error) {
console.error('Test print error:', error);
showError('Test print failed: ' + error.message);
} finally {
elements.testPrintBtn.disabled = false;
elements.testPrintBtn.textContent = 'Test Print';
}
}
/**
* Get available printers
*/
async function getPrinters() {
try {
elements.getPrintersBtn.disabled = true;
elements.getPrintersBtn.textContent = 'Loading...';
// Get printers from background script
const result = await new Promise((resolve) => {
chrome.runtime.sendMessage({ action: 'get_printers' }, resolve);
});
if (result && result.success && result.printers) {
displayPrinters(result.printers);
} else {
showError(result ? result.error : 'Failed to get printers');
}
} catch (error) {
console.error('Get printers error:', error);
showError('Failed to get printers: ' + error.message);
} finally {
elements.getPrintersBtn.disabled = false;
elements.getPrintersBtn.textContent = 'Get Printers';
}
}
/**
* Display printers list
*/
function displayPrinters(printers) {
if (!printers || printers.length === 0) {
elements.printersList.innerHTML = '<div style="color: #666; font-style: italic;">No printers found</div>';
} else {
elements.printersList.innerHTML = printers.map(printer => `
<div class="printer-item">
<div class="printer-name">${escapeHtml(printer.name)}</div>
<div class="printer-details">
Driver: ${escapeHtml(printer.driver || 'Unknown')}<br>
Port: ${escapeHtml(printer.port || 'Unknown')}
</div>
</div>
`).join('');
}
elements.printersContainer.classList.remove('hidden');
}
/**
* Show success message
*/
function showSuccess(message) {
const statusCard = elements.serviceStatus;
const statusMessage = elements.statusMessage;
const statusDetail = elements.statusDetail;
statusCard.className = 'status-card';
statusMessage.textContent = message;
statusDetail.textContent = new Date().toLocaleTimeString();
// Reset after 3 seconds
setTimeout(() => {
checkServiceStatus();
}, 3000);
}
/**
* Show error message
*/
function showError(message) {
const statusCard = elements.serviceStatus;
const statusMessage = elements.statusMessage;
const statusDetail = elements.statusDetail;
statusCard.className = 'status-card error';
statusMessage.textContent = 'Error: ' + message;
statusDetail.textContent = new Date().toLocaleTimeString();
}
/**
* Show help information
*/
function showHelp() {
const helpText = `
Quality Label Printing Service Help
==================================
Installation:
1. Install the Windows Print Service using install_service.bat
2. Install this Chrome extension
3. Configure your application to use localhost:8765
API Endpoints:
• http://localhost:8765/health - Service health check
• http://localhost:8765/print/pdf - Print PDF files
• http://localhost:8765/print/silent - Silent printing
• http://localhost:8765/printers - Get available printers
Troubleshooting:
• Ensure Windows service is running
• Check firewall settings (port 8765)
• Verify Chrome extension permissions
• Check service logs: print_service.log
For support, contact the Quality Label Printing development team.
`;
alert(helpText.trim());
}
/**
* Escape HTML to prevent XSS
*/
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
});

View File

@@ -1,424 +0,0 @@
#!/usr/bin/env python3
"""
Script to create a completely self-contained Windows Print Service package
with embedded Python distribution and comprehensive Error 1053 fixes
- Zero external dependencies required!
- Multiple installation methods with automatic fallback
- Complete Windows Service Error 1053 resolution
"""
import os
import sys
import zipfile
import urllib.request
import tempfile
import shutil
from pathlib import Path
# Python embeddable version details
PYTHON_VERSION = "3.11.9"
PYTHON_DOWNLOAD_URL = f"https://www.python.org/ftp/python/{PYTHON_VERSION}/python-{PYTHON_VERSION}-embed-amd64.zip"
PYTHON_DIR_NAME = "python_embedded"
def download_portable_python(temp_dir):
"""Download and extract Python embedded distribution"""
print(f"📥 Downloading Python {PYTHON_VERSION} embedded distribution...")
python_zip_path = os.path.join(temp_dir, "python-embed.zip")
try:
# Download Python embedded
urllib.request.urlretrieve(PYTHON_DOWNLOAD_URL, python_zip_path)
print(f"✅ Downloaded Python to: {python_zip_path}")
# Create extraction directory
python_extract_dir = os.path.join(temp_dir, PYTHON_DIR_NAME)
os.makedirs(python_extract_dir, exist_ok=True)
# Extract Python
with zipfile.ZipFile(python_zip_path, 'r') as zip_ref:
zip_ref.extractall(python_extract_dir)
print(f"✅ Extracted Python to: {python_extract_dir}")
# Enable site-packages by modifying pth file
pth_files = [f for f in os.listdir(python_extract_dir) if f.endswith('._pth')]
if pth_files:
pth_file = os.path.join(python_extract_dir, pth_files[0])
with open(pth_file, 'a') as f:
f.write('\nimport site\n')
print("✅ Enabled site-packages in embedded Python")
return python_extract_dir
except Exception as e:
print(f"❌ Failed to download Python: {e}")
return None
def create_complete_package():
"""Create complete self-contained package with embedded Python"""
# Get current directory (should be windows_print_service)
current_dir = Path(__file__).parent
print(f"📂 Working from: {current_dir}")
# Create temporary directory
with tempfile.TemporaryDirectory() as temp_dir:
print(f"🔧 Using temporary directory: {temp_dir}")
# Download and extract portable Python
python_dir = download_portable_python(temp_dir)
if not python_dir:
print("❌ Failed to prepare Python distribution")
return False
# Create the complete package
package_path = current_dir / "QualityPrintService_COMPLETE_ZERO_DEPENDENCIES.zip"
print(f"📦 Creating complete package: {package_path}")
with zipfile.ZipFile(package_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
files_added = 0
# Add Python embedded distribution
print("📁 Adding Python embedded distribution...")
for root, dirs, files in os.walk(python_dir):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.join(PYTHON_DIR_NAME, os.path.relpath(file_path, python_dir))
zipf.write(file_path, arcname)
files_added += 1
# Add all service files
print("📁 Adding service files...")
service_files = [
"print_service_complete.py",
"service_wrapper.py",
"service_installer.py",
"install_service_complete.bat",
"install_service_ENHANCED.bat",
"uninstall_service_complete.bat",
"fix_error_1053.bat",
"test_service.bat",
"build_executable.bat",
"build_package.py",
"create_portable_package.py",
"requirements_complete.txt",
"INSTALLATION_COMPLETE.md",
"PACKAGE_SUMMARY.md",
"README_COMPLETE.md",
"TROUBLESHOOTING_1053.md",
"ERROR_1053_COMPLETE_FIX.md",
"PORTABLE_PYTHON_INSTRUCTIONS.txt"
]
for file_name in service_files:
file_path = current_dir / file_name
if file_path.exists():
zipf.write(file_path, file_name)
files_added += 1
print(f" ✅ Added: {file_name}")
# Add Chrome extension
chrome_ext_dir = current_dir / "chrome_extension"
if chrome_ext_dir.exists():
print("📁 Adding Chrome extension...")
for root, dirs, files in os.walk(chrome_ext_dir):
for file in files:
if not file.startswith('.'):
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, current_dir)
zipf.write(file_path, arcname)
files_added += 1
# Create updated installer that uses embedded Python
updated_installer = f'''@echo off
setlocal enabledelayedexpansion
echo ========================================
echo Quality Label Print Service Installer
echo ZERO DEPENDENCIES - COMPLETE PACKAGE
echo ========================================
echo.
echo This package includes EVERYTHING needed:
echo ✅ Embedded Python {PYTHON_VERSION}
echo ✅ Complete Print Service
echo ✅ Windows Service Installer
echo ✅ Chrome Extension
echo ✅ Auto-recovery System
echo.
REM Check for administrator privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
echo ❌ ERROR: Administrator privileges required
echo Please right-click this file and select "Run as administrator"
echo.
pause
exit /b 1
)
echo [1/7] Administrator privileges confirmed ✅
echo.
REM Set variables
set CURRENT_DIR=%~dp0
set SERVICE_NAME=QualityPrintService
set SERVICE_DISPLAY_NAME=Quality Label Print Service
set INSTALL_DIR=C:\\QualityPrintService
set PYTHON_EXE=%INSTALL_DIR%\\{PYTHON_DIR_NAME}\\python.exe
set PYTHON_SCRIPT=%INSTALL_DIR%\\print_service_complete.py
set LOG_DIR=%USERPROFILE%\\PrintService\\logs
echo [2/7] Using embedded Python distribution ✅
echo Python location: %PYTHON_EXE%
echo.
REM Stop existing service if running
echo [3/7] Stopping existing service (if any)...
sc query "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo Stopping existing service...
net stop "%SERVICE_NAME%" >nul 2>&1
sc delete "%SERVICE_NAME%" >nul 2>&1
timeout /t 2 >nul
)
echo Service cleanup completed ✅
echo.
REM Create installation directory
echo [4/7] Creating installation directory...
if exist "%INSTALL_DIR%" (
echo Removing old installation...
rmdir /s /q "%INSTALL_DIR%" >nul 2>&1
)
mkdir "%INSTALL_DIR%" >nul 2>&1
echo Installation directory: %INSTALL_DIR% ✅
echo.
REM Copy all files to installation directory
echo [5/7] Installing service files...
echo Copying embedded Python...
xcopy "%CURRENT_DIR%{PYTHON_DIR_NAME}" "%INSTALL_DIR%\\{PYTHON_DIR_NAME}\\" /E /I /Y >nul
echo Copying service script...
copy "%CURRENT_DIR%print_service_complete.py" "%INSTALL_DIR%\\" >nul
echo Service files installed ✅
echo.
REM Create log directory
echo [6/7] Setting up logging...
mkdir "%LOG_DIR%" >nul 2>&1
echo Log directory: %LOG_DIR% ✅
echo.
REM Install and start Windows service
echo [7/7] Installing Windows service...
sc create "%SERVICE_NAME%" binPath= "\\"%PYTHON_EXE%\\" \\"%PYTHON_SCRIPT%\\"" DisplayName= "%SERVICE_DISPLAY_NAME%" start= auto
if %errorLevel% neq 0 (
echo ❌ Failed to create Windows service
pause
exit /b 1
)
REM Configure service recovery
sc failure "%SERVICE_NAME%" reset= 60 actions= restart/10000/restart/30000/restart/60000
sc config "%SERVICE_NAME%" depend= ""
REM Start the service
echo Starting service...
net start "%SERVICE_NAME%"
if %errorLevel% neq 0 (
echo ⚠️ Service created but failed to start immediately
echo This is normal - the service will start automatically on reboot
) else (
echo Service started successfully ✅
)
echo.
echo ========================================
echo INSTALLATION COMPLETED! 🎉
echo ========================================
echo.
echo ✅ Python embedded distribution installed
echo ✅ Windows Print Service installed and configured
echo ✅ Auto-recovery enabled (restarts on failure)
echo ✅ Service will start automatically on boot
echo.
echo 🌐 Service URL: http://localhost:8765
echo 📊 Health check: http://localhost:8765/health
echo 📁 Logs location: %LOG_DIR%
echo.
echo 📋 NEXT STEPS:
echo 1. Install Chrome extension from 'chrome_extension' folder
echo 2. Test service: http://localhost:8765/health
echo 3. Configure web application to use service
echo.
echo Press any key to test service connection...
pause >nul
REM Test service
echo Testing service connection...
timeout /t 3 >nul
curl -s http://localhost:8765/health >nul 2>&1
if %errorLevel% equ 0 (
echo ✅ Service is responding correctly!
) else (
echo ⚠️ Service test failed - may need a moment to start
echo Check logs in: %LOG_DIR%
)
echo.
echo Installation complete! Service is ready to use.
pause
'''
# Add the updated installer
zipf.writestr("install_service_ZERO_DEPENDENCIES.bat", updated_installer)
files_added += 1
# Add comprehensive README
readme_content = f'''# Quality Print Service - ZERO DEPENDENCIES Package
## 🎯 COMPLETE SELF-CONTAINED INSTALLATION
This package contains EVERYTHING needed to run the Quality Print Service:
### ✅ What's Included:
- **Embedded Python {PYTHON_VERSION}** - No system Python required!
- **Complete Print Service** - Zero external dependencies
- **Windows Service Installer** - Automatic installation and recovery
- **Chrome Extension** - Web browser integration
- **Comprehensive Documentation** - Installation and usage guides
### 🚀 INSTALLATION (5 Minutes):
#### Requirements:
- Windows 10/11 or Windows Server 2016+
- Administrator privileges (for service installation)
- Google Chrome browser
#### Step 1: Extract Package
- Extract this ZIP file to any location (Desktop, Downloads, etc.)
- No permanent location needed - installer copies files automatically
#### Step 2: Install Service
- Right-click `install_service_ZERO_DEPENDENCIES.bat`
- Select "Run as administrator"
- Follow the installation prompts
#### Step 3: Install Chrome Extension
- Open Chrome browser
- Navigate to `chrome://extensions/`
- Enable "Developer mode" (toggle in top-right)
- Click "Load unpacked"
- Select the `chrome_extension` folder from extracted package
#### Step 4: Test Installation
- Visit: http://localhost:8765/health
- Should return: {{"status": "healthy", "service": "Windows Print Service"}}
### 🔧 Technical Details:
**Service Architecture:**
```
Quality Web App → Chrome Extension → Windows Service → Printer
```
**Printing Methods (automatic fallback):**
1. Adobe Reader (silent printing)
2. SumatraPDF (if Adobe unavailable)
3. PowerShell Print-Document
4. Microsoft Edge (fallback)
5. Windows default printer
**Service Management:**
- Automatic startup on Windows boot
- Auto-recovery on failure (3 restart attempts)
- Comprehensive logging in: `%USERPROFILE%\\PrintService\\logs\\`
**Network Configuration:**
- Service runs on: http://localhost:8765
- Chrome extension communicates via this local endpoint
- No external network access required
### 📂 Package Contents:
```
QualityPrintService_COMPLETE_ZERO_DEPENDENCIES.zip
├── python_embedded/ # Python {PYTHON_VERSION} embedded
├── print_service_complete.py # Main service script
├── install_service_ZERO_DEPENDENCIES.bat # Installer
├── chrome_extension/ # Browser extension
│ ├── manifest.json
│ ├── background.js
│ ├── content.js
│ ├── popup.html
│ └── popup.js
└── README.md # This file
```
### 🛠️ Troubleshooting:
**Service Won't Start:**
1. Check Windows Event Viewer → Windows Logs → Application
2. Check service logs in: `%USERPROFILE%\\PrintService\\logs\\`
3. Verify Python embedded installation in: `C:\\QualityPrintService\\`
**Chrome Extension Not Working:**
1. Verify extension is enabled in `chrome://extensions/`
2. Check browser console for error messages
3. Ensure service is running: http://localhost:8765/health
**Printing Issues:**
1. Verify printer is installed and accessible
2. Check service logs for printing attempts
3. Test manual PDF printing to verify printer functionality
### 🔄 Uninstallation:
```cmd
# Stop and remove service
sc stop QualityPrintService
sc delete QualityPrintService
# Remove installation directory
rmdir /s /q C:\\QualityPrintService
# Remove Chrome extension manually from chrome://extensions/
```
### 📞 Support:
- Service logs: `%USERPROFILE%\\PrintService\\logs\\service.log`
- Health check: http://localhost:8765/health
- Printer list: http://localhost:8765/printers
---
**Package Version:** Complete Zero Dependencies
**Python Version:** {PYTHON_VERSION} (Embedded)
**Created:** {os.path.basename(__file__)}
'''
zipf.writestr("README_ZERO_DEPENDENCIES.md", readme_content)
files_added += 1
print(f"\n📦 Enhanced Package created successfully!")
print(f"📄 Total files: {files_added}")
print(f"📂 Location: {package_path}")
print(f"📏 Size: {package_path.stat().st_size / 1024 / 1024:.1f} MB")
print(f"🔧 Features: Error 1053 fixes, multiple installation methods")
print(f"🚀 Python: {PYTHON_VERSION} embedded (zero dependencies)")
return True
if __name__ == "__main__":
print("🚀 Creating Enhanced Package with Error 1053 Fixes...")
print("=" * 65)
if create_complete_package():
print("\n✅ SUCCESS: Enhanced package created with Error 1053 fixes!")
print("\n📋 Next steps:")
print("1. Package includes multiple installation methods")
print("2. Error 1053 diagnostic and fix tools included")
print("3. Test on Windows system - should resolve all service issues")
print("4. Update Flask app to serve this enhanced package")
else:
print("\n❌ FAILED: Package creation failed")
sys.exit(1)

View File

@@ -1,454 +0,0 @@
@echo off
REM Windows Service Error 1053 - COMPREHENSIVE DIAGNOSTIC TOOL
REM This script diagnoses and fixes the most common causes of Error 1053
setlocal enabledelayedexpansion
echo =========================================
echo ERROR 1053 DIAGNOSTIC TOOL
echo Quality Print Service Troubleshooter
echo =========================================
echo.
echo This tool diagnoses and fixes Windows Service Error 1053:
echo "The service did not respond to the start or control request in a timely fashion"
echo.
REM Check for administrator privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
echo ❌ CRITICAL: Administrator privileges required
echo Right-click this file and select "Run as administrator"
echo.
pause
exit /b 1
)
echo ✅ Administrator privileges confirmed
echo.
REM Set variables
set CURRENT_DIR=%~dp0
set SERVICE_NAME=QualityPrintService
set INSTALL_DIR=C:\QualityPrintService
set LOG_DIR=%USERPROFILE%\PrintService\logs
echo ===========================================
echo [STEP 1] SERVICE STATUS DIAGNOSIS
echo ===========================================
REM Check current service status
echo Checking service status...
sc query "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo Service exists - checking status:
sc query "%SERVICE_NAME%"
echo.
REM Get detailed service info
echo Service configuration:
sc qc "%SERVICE_NAME%"
echo.
) else (
echo ❌ Service not found - needs installation
echo.
)
REM Check Task Scheduler
echo Checking Task Scheduler...
schtasks /query /tn "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo ✅ Task Scheduler entry found
schtasks /query /tn "%SERVICE_NAME%" /fo LIST
echo.
) else (
echo ❌ Task Scheduler entry not found
echo.
)
echo ===========================================
echo [STEP 2] PROCESS AND PORT DIAGNOSIS
echo ===========================================
REM Check for running processes
echo Checking for existing service processes...
tasklist /fi "imagename eq python.exe" | findstr python.exe >nul 2>&1
if %errorLevel% equ 0 (
echo Python processes found:
tasklist /fi "imagename eq python.exe"
echo.
) else (
echo No Python processes running
echo.
)
REM Check port 8765
echo Checking port 8765...
netstat -an | findstr :8765 >nul 2>&1
if %errorLevel% equ 0 (
echo ⚠️ Port 8765 is in use:
netstat -an | findstr :8765
echo.
REM Find process using port
for /f "tokens=5" %%a in ('netstat -ano ^| findstr :8765') do (
tasklist /fi "pid eq %%a" 2>nul | findstr /v "INFO:"
)
echo.
) else (
echo ✅ Port 8765 is available
echo.
)
echo ===========================================
echo [STEP 3] PYTHON ENVIRONMENT DIAGNOSIS
echo ===========================================
REM Check Python installations
echo Checking Python installations...
REM Check embedded Python
if exist "%INSTALL_DIR%\python_embedded\python.exe" (
echo ✅ Embedded Python found: %INSTALL_DIR%\python_embedded\python.exe
"%INSTALL_DIR%\python_embedded\python.exe" --version 2>nul
echo.
) else (
echo ❌ Embedded Python not found at %INSTALL_DIR%\python_embedded\python.exe
)
if exist "%CURRENT_DIR%python_embedded\python.exe" (
echo ✅ Installer embedded Python found: %CURRENT_DIR%python_embedded\python.exe
"%CURRENT_DIR%python_embedded\python.exe" --version 2>nul
echo.
) else (
echo ❌ Installer embedded Python not found
)
REM Check system Python
python --version >nul 2>&1
if %errorLevel% equ 0 (
echo ✅ System Python found:
python --version
where python
echo.
) else (
echo ❌ System Python not found in PATH
echo.
)
echo ===========================================
echo [STEP 4] FILE SYSTEM DIAGNOSIS
echo ===========================================
REM Check installation files
echo Checking installation files...
if exist "%INSTALL_DIR%" (
echo ✅ Installation directory exists: %INSTALL_DIR%
echo Contents:
dir "%INSTALL_DIR%" /b
echo.
if exist "%INSTALL_DIR%\print_service_complete.py" (
echo ✅ Main service script found
) else (
echo ❌ Main service script missing
)
if exist "%INSTALL_DIR%\enhanced_service_wrapper.bat" (
echo ✅ Service wrapper found
) else (
echo ❌ Service wrapper missing
)
) else (
echo ❌ Installation directory not found: %INSTALL_DIR%
)
REM Check log directory
if exist "%LOG_DIR%" (
echo ✅ Log directory exists: %LOG_DIR%
if exist "%LOG_DIR%\service_wrapper.log" (
echo Recent log entries:
echo ==================
powershell -Command "Get-Content '%LOG_DIR%\service_wrapper.log' -Tail 10" 2>nul
echo ==================
echo.
)
) else (
echo ❌ Log directory not found: %LOG_DIR%
mkdir "%LOG_DIR%" >nul 2>&1
echo Created log directory
)
echo ===========================================
echo [STEP 5] SERVICE TEST
echo ===========================================
REM Determine Python executable
set PYTHON_EXE=
if exist "%INSTALL_DIR%\python_embedded\python.exe" (
set PYTHON_EXE=%INSTALL_DIR%\python_embedded\python.exe
) else if exist "%CURRENT_DIR%python_embedded\python.exe" (
set PYTHON_EXE=%CURRENT_DIR%python_embedded\python.exe
) else (
python --version >nul 2>&1
if !errorLevel! equ 0 (
set PYTHON_EXE=python
)
)
if "!PYTHON_EXE!"=="" (
echo ❌ CRITICAL: No Python executable found
echo Cannot perform service test
goto :fixes
)
echo Testing service with Python: !PYTHON_EXE!
REM Test service script
if exist "%INSTALL_DIR%\print_service_complete.py" (
cd /d "%INSTALL_DIR%"
echo Testing service script syntax...
"!PYTHON_EXE!" -m py_compile print_service_complete.py
if !errorLevel! equ 0 (
echo ✅ Service script syntax OK
) else (
echo ❌ Service script syntax error
)
echo Testing service functionality...
"!PYTHON_EXE!" print_service_complete.py --test
if !errorLevel! equ 0 (
echo ✅ Service test passed
) else (
echo ❌ Service test failed
)
REM Quick standalone test
echo Testing standalone mode (15 seconds)...
start /min "" "!PYTHON_EXE!" print_service_complete.py --standalone
timeout /t 5 >nul
REM Test connection
curl -s http://localhost:8765/health >nul 2>&1
if !errorLevel! equ 0 (
echo ✅ Service responding in standalone mode
REM Stop standalone service
taskkill /f /im python.exe >nul 2>&1
) else (
powershell -Command "try { Invoke-WebRequest -Uri 'http://localhost:8765/health' -UseBasicParsing } catch { exit 1 }" >nul 2>&1
if !errorLevel! equ 0 (
echo ✅ Service responding in standalone mode
taskkill /f /im python.exe >nul 2>&1
) else (
echo ❌ Service not responding in standalone mode
taskkill /f /im python.exe >nul 2>&1
)
)
) else (
echo ❌ Service script not found at %INSTALL_DIR%\print_service_complete.py
)
echo.
:fixes
echo ===========================================
echo [STEP 6] AUTOMATED FIXES FOR ERROR 1053
echo ===========================================
echo Applying automated fixes...
REM Fix 1: Stop conflicting services
echo [FIX 1] Stopping any conflicting services...
net stop "%SERVICE_NAME%" >nul 2>&1
schtasks /end /tn "%SERVICE_NAME%" >nul 2>&1
taskkill /f /im python.exe >nul 2>&1
timeout /t 3 >nul
echo ✅ Services stopped
REM Fix 2: Remove old service entries
echo [FIX 2] Cleaning old service entries...
sc delete "%SERVICE_NAME%" >nul 2>&1
schtasks /delete /tn "%SERVICE_NAME%" /f >nul 2>&1
echo ✅ Old entries removed
REM Fix 3: Create enhanced service wrapper with timeout handling
echo [FIX 3] Creating enhanced service wrapper...
set ENHANCED_WRAPPER=%INSTALL_DIR%\error_1053_fix_wrapper.bat
mkdir "%INSTALL_DIR%" >nul 2>&1
echo @echo off > "%ENHANCED_WRAPPER%"
echo REM Enhanced Windows Service Wrapper - Error 1053 Fix >> "%ENHANCED_WRAPPER%"
echo REM This wrapper includes specific fixes for SCM timeout issues >> "%ENHANCED_WRAPPER%"
echo. >> "%ENHANCED_WRAPPER%"
echo setlocal >> "%ENHANCED_WRAPPER%"
echo. >> "%ENHANCED_WRAPPER%"
echo REM Logging >> "%ENHANCED_WRAPPER%"
echo set LOG_FILE=%LOG_DIR%\error_1053_fix.log >> "%ENHANCED_WRAPPER%"
echo echo %%date%% %%time%% - Service wrapper starting... ^>^> "%%LOG_FILE%%" >> "%ENHANCED_WRAPPER%"
echo. >> "%ENHANCED_WRAPPER%"
echo REM Change to service directory >> "%ENHANCED_WRAPPER%"
echo cd /d "%INSTALL_DIR%" >> "%ENHANCED_WRAPPER%"
echo. >> "%ENHANCED_WRAPPER%"
echo REM Pre-flight checks >> "%ENHANCED_WRAPPER%"
if "!PYTHON_EXE!" neq "" (
echo if not exist "!PYTHON_EXE!" ( >> "%ENHANCED_WRAPPER%"
echo echo ERROR: Python not found at !PYTHON_EXE! ^>^> "%%LOG_FILE%%" >> "%ENHANCED_WRAPPER%"
echo exit /b 1 >> "%ENHANCED_WRAPPER%"
echo ^) >> "%ENHANCED_WRAPPER%"
)
echo. >> "%ENHANCED_WRAPPER%"
echo if not exist "print_service_complete.py" ( >> "%ENHANCED_WRAPPER%"
echo echo ERROR: Service script not found ^>^> "%%LOG_FILE%%" >> "%ENHANCED_WRAPPER%"
echo exit /b 1 >> "%ENHANCED_WRAPPER%"
echo ^) >> "%ENHANCED_WRAPPER%"
echo. >> "%ENHANCED_WRAPPER%"
echo REM Quick response to SCM - Start service immediately in background >> "%ENHANCED_WRAPPER%"
echo echo Service responding to SCM... ^>^> "%%LOG_FILE%%" >> "%ENHANCED_WRAPPER%"
echo. >> "%ENHANCED_WRAPPER%"
echo REM Start the actual service process >> "%ENHANCED_WRAPPER%"
if "!PYTHON_EXE!" neq "" (
echo start /b "Quality Print Service" "!PYTHON_EXE!" "print_service_complete.py" --service >> "%ENHANCED_WRAPPER%"
) else (
echo start /b "Quality Print Service" python "print_service_complete.py" --service >> "%ENHANCED_WRAPPER%"
)
echo. >> "%ENHANCED_WRAPPER%"
echo REM Keep wrapper alive briefly to satisfy SCM >> "%ENHANCED_WRAPPER%"
echo timeout /t 2 /nobreak ^>nul >> "%ENHANCED_WRAPPER%"
echo. >> "%ENHANCED_WRAPPER%"
echo echo Service started successfully ^>^> "%%LOG_FILE%%" >> "%ENHANCED_WRAPPER%"
echo exit /b 0 >> "%ENHANCED_WRAPPER%"
echo ✅ Enhanced wrapper created
REM Fix 4: Install service with proper timeout settings
echo [FIX 4] Installing service with Error 1053 fixes...
REM Create service with extended timeout
sc create "%SERVICE_NAME%" binPath= "\"%ENHANCED_WRAPPER%\"" DisplayName= "Quality Print Service (Error 1053 Fixed)" start= auto >nul 2>&1
if %errorLevel% equ 0 (
echo ✅ Service created successfully
REM Configure service for Error 1053 prevention
echo Configuring service recovery...
sc failure "%SERVICE_NAME%" reset= 86400 actions= restart/5000/restart/5000/restart/5000 >nul 2>&1
REM Set service to auto-start with delay
sc config "%SERVICE_NAME%" start= delayed-auto >nul 2>&1
echo ✅ Service configured with Error 1053 fixes
) else (
echo ❌ Service creation failed
)
echo.
echo ===========================================
echo [STEP 7] SERVICE START TEST
echo ===========================================
echo Testing service start with Error 1053 fixes...
REM Start service
net start "%SERVICE_NAME%" 2>&1
if %errorLevel% equ 0 (
echo ✅ SERVICE STARTED SUCCESSFULLY!
echo Error 1053 has been FIXED! 🎉
REM Wait and test connection
echo Waiting for service to initialize...
timeout /t 10 >nul
echo Testing service connection...
curl -s http://localhost:8765/health >nul 2>&1
if !errorLevel! equ 0 (
echo ✅ Service is responding properly
echo.
echo ========================================
echo PROBLEM SOLVED! 🎉
echo ========================================
echo.
echo ✅ Windows Service Error 1053 FIXED
echo ✅ Service: %SERVICE_NAME%
echo ✅ Status: Running and responding
echo ✅ URL: http://localhost:8765
echo.
goto :success
) else (
powershell -Command "try { Invoke-WebRequest -Uri 'http://localhost:8765/health' -UseBasicParsing } catch { exit 1 }" >nul 2>&1
if !errorLevel! equ 0 (
echo ✅ Service is responding properly
goto :success
) else (
echo ⚠️ Service started but not responding
echo Check logs: %LOG_DIR%\error_1053_fix.log
)
)
) else (
echo ❌ Service start failed - Error 1053 may persist
echo.
echo ===========================================
echo [ALTERNATIVE SOLUTIONS]
echo ===========================================
echo.
echo Since SC Service failed, trying alternative methods...
REM Alternative: Task Scheduler
echo Installing via Task Scheduler...
schtasks /create /tn "%SERVICE_NAME%" /tr "\"%ENHANCED_WRAPPER%\"" /sc onstart /ru SYSTEM /rl HIGHEST >nul 2>&1
if !errorLevel! equ 0 (
echo ✅ Task Scheduler service created
schtasks /run /tn "%SERVICE_NAME%" >nul 2>&1
if !errorLevel! equ 0 (
echo ✅ Task Scheduler service started
echo Alternative solution: Task Scheduler
)
)
REM Alternative: Manual startup
echo.
echo Manual startup option:
echo Run this command to start manually:
echo "%ENHANCED_WRAPPER%"
)
:success
echo.
echo ===========================================
echo [STEP 8] SUMMARY AND RECOMMENDATIONS
echo ===========================================
echo Diagnostic complete!
echo.
echo 📋 TROUBLESHOOTING SUMMARY:
echo ✅ Administrator privileges: OK
echo ✅ Enhanced service wrapper: Created
echo ✅ Error 1053 fixes: Applied
echo ✅ Service configuration: Updated
echo.
if exist "%LOG_DIR%\error_1053_fix.log" (
echo 📊 Recent service logs:
echo ========================
powershell -Command "Get-Content '%LOG_DIR%\error_1053_fix.log' -Tail 5" 2>nul
echo ========================
echo.
)
echo 🔧 Service Management Commands:
echo - Start: net start %SERVICE_NAME%
echo - Stop: net stop %SERVICE_NAME%
echo - Status: sc query %SERVICE_NAME%
echo.
echo 📁 Log files: %LOG_DIR%
echo 🌐 Service URL: http://localhost:8765
echo 🔍 Health check: http://localhost:8765/health
echo.
echo Press any key to exit...
pause >nul

View File

@@ -1,407 +0,0 @@
@echo off
REM Windows Print Service - ENHANCED INSTALLER - Fixes Error 1053
REM This installer addresses the most common causes of Windows Service startup failures
setlocal enabledelayedexpansion
echo =========================================
echo Quality Print Service - ENHANCED INSTALLER
echo Fixes Windows Service Error 1053
echo =========================================
echo.
echo This installer includes multiple methods to ensure service starts:
echo ✅ Windows SC Service (preferred)
echo ✅ Task Scheduler Service (fallback)
echo ✅ Startup Script (manual fallback)
echo ✅ Enhanced error detection and recovery
echo.
REM Check for administrator privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
echo ❌ ERROR: Administrator privileges required
echo Please right-click this file and select "Run as administrator"
echo.
pause
exit /b 1
)
echo [1/8] Administrator privileges confirmed ✅
echo.
REM Set variables
set CURRENT_DIR=%~dp0
set SERVICE_NAME=QualityPrintService
set SERVICE_DISPLAY_NAME=Quality Print Service
set INSTALL_DIR=C:\QualityPrintService
set LOG_DIR=%USERPROFILE%\PrintService\logs
REM Detect Python executable
echo [2/8] Detecting Python installation...
set PYTHON_EXE=
set PYTHON_SCRIPT=%INSTALL_DIR%\print_service_complete.py
REM Check for embedded Python first
if exist "%INSTALL_DIR%\python_embedded\python.exe" (
set PYTHON_EXE=%INSTALL_DIR%\python_embedded\python.exe
echo Found embedded Python: !PYTHON_EXE!
) else if exist "%CURRENT_DIR%python_embedded\python.exe" (
set PYTHON_EXE=%CURRENT_DIR%python_embedded\python.exe
echo Found embedded Python in installer: !PYTHON_EXE!
) else (
REM Check system Python
python --version >nul 2>&1
if !errorLevel! equ 0 (
set PYTHON_EXE=python
echo Found system Python ✅
) else (
echo ❌ ERROR: Python not found
echo Please ensure Python 3.7+ is installed or use the zero-dependency package
pause
exit /b 1
)
)
echo.
REM Stop existing service
echo [3/8] Stopping existing service (if any)...
sc query "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo Stopping existing service...
net stop "%SERVICE_NAME%" >nul 2>&1
sc delete "%SERVICE_NAME%" >nul 2>&1
timeout /t 3 >nul
)
REM Stop any existing task
schtasks /end /tn "%SERVICE_NAME%" >nul 2>&1
schtasks /delete /tn "%SERVICE_NAME%" /f >nul 2>&1
echo Service cleanup completed ✅
echo.
REM Create installation directory
echo [4/8] Creating installation directory...
if exist "%INSTALL_DIR%" (
echo Removing old installation...
rmdir /s /q "%INSTALL_DIR%" >nul 2>&1
)
mkdir "%INSTALL_DIR%" >nul 2>&1
REM Create log directory
mkdir "%LOG_DIR%" >nul 2>&1
echo Installation directory: %INSTALL_DIR%
echo Log directory: %LOG_DIR%
echo.
REM Copy service files
echo [5/8] Installing service files...
REM Copy Python embedded if available
if exist "%CURRENT_DIR%python_embedded\" (
echo Copying embedded Python distribution...
xcopy "%CURRENT_DIR%python_embedded" "%INSTALL_DIR%\python_embedded\" /E /I /Y >nul
set PYTHON_EXE=%INSTALL_DIR%\python_embedded\python.exe
echo Embedded Python installed ✅
)
REM Copy service scripts
copy "%CURRENT_DIR%print_service_complete.py" "%INSTALL_DIR%\" >nul
copy "%CURRENT_DIR%service_wrapper.py" "%INSTALL_DIR%\" >nul 2>&1
copy "%CURRENT_DIR%service_installer.py" "%INSTALL_DIR%\" >nul 2>&1
echo Service files installed ✅
echo.
REM Test service before installing
echo [6/8] Testing service functionality...
cd /d "%INSTALL_DIR%"
echo Testing Python and service script...
"%PYTHON_EXE%" "%PYTHON_SCRIPT%" --test >nul 2>&1
if %errorLevel% equ 0 (
echo Service test passed ✅
) else (
echo ⚠️ Service test failed - continuing with installation
)
REM Check port availability
echo Testing port 8765 availability...
netstat -an | findstr :8765 >nul 2>&1
if %errorLevel% equ 0 (
echo ⚠️ Port 8765 is in use - service may conflict
) else (
echo Port 8765 available ✅
)
echo.
REM Install service - Multiple methods
echo [7/8] Installing Windows service with multiple fallback methods...
REM Create enhanced service wrapper
set WRAPPER_BAT=%INSTALL_DIR%\enhanced_service_wrapper.bat
echo @echo off > "%WRAPPER_BAT%"
echo REM Enhanced Windows Service Wrapper - Error 1053 Fix >> "%WRAPPER_BAT%"
echo cd /d "%INSTALL_DIR%" >> "%WRAPPER_BAT%"
echo. >> "%WRAPPER_BAT%"
echo REM Log service start attempt >> "%WRAPPER_BAT%"
echo echo %%date%% %%time%% - Service wrapper starting... ^>^> "%LOG_DIR%\service_wrapper.log" >> "%WRAPPER_BAT%"
echo. >> "%WRAPPER_BAT%"
echo REM Verify files exist >> "%WRAPPER_BAT%"
echo if not exist "%PYTHON_EXE%" ( >> "%WRAPPER_BAT%"
echo echo ERROR: Python not found at %PYTHON_EXE% ^>^> "%LOG_DIR%\service_wrapper.log" >> "%WRAPPER_BAT%"
echo exit /b 1 >> "%WRAPPER_BAT%"
echo ^) >> "%WRAPPER_BAT%"
echo. >> "%WRAPPER_BAT%"
echo if not exist "%PYTHON_SCRIPT%" ( >> "%WRAPPER_BAT%"
echo echo ERROR: Service script not found ^>^> "%LOG_DIR%\service_wrapper.log" >> "%WRAPPER_BAT%"
echo exit /b 1 >> "%WRAPPER_BAT%"
echo ^) >> "%WRAPPER_BAT%"
echo. >> "%WRAPPER_BAT%"
echo REM Start service with error handling >> "%WRAPPER_BAT%"
echo echo Starting service process... ^>^> "%LOG_DIR%\service_wrapper.log" >> "%WRAPPER_BAT%"
echo "%PYTHON_EXE%" "%PYTHON_SCRIPT%" --service >> "%WRAPPER_BAT%"
echo. >> "%WRAPPER_BAT%"
echo REM Log exit code >> "%WRAPPER_BAT%"
echo echo Service exited with code %%errorlevel%% ^>^> "%LOG_DIR%\service_wrapper.log" >> "%WRAPPER_BAT%"
REM Method 1: Windows SC Service
echo Installing as Windows SC Service...
sc create "%SERVICE_NAME%" binPath= "\"%WRAPPER_BAT%\"" DisplayName= "%SERVICE_DISPLAY_NAME%" start= auto >nul 2>&1
if %errorLevel% equ 0 (
echo Windows SC Service created ✅
REM Configure recovery
sc failure "%SERVICE_NAME%" reset= 86400 actions= restart/5000/restart/5000/restart/5000 >nul 2>&1
REM Try to start service
echo Starting SC service...
net start "%SERVICE_NAME%" >nul 2>&1
if !errorLevel! equ 0 (
echo SC Service started successfully ✅
set SERVICE_METHOD=SC_SERVICE
goto :service_installed
) else (
echo ⚠️ SC Service created but failed to start - trying Task Scheduler...
)
) else (
echo ❌ SC Service creation failed - trying Task Scheduler...
)
REM Method 2: Task Scheduler Service
echo Installing as Task Scheduler Service...
REM Create task XML
set TASK_XML=%INSTALL_DIR%\%SERVICE_NAME%_task.xml
echo ^<?xml version="1.0" encoding="UTF-16"?^> > "%TASK_XML%"
echo ^<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"^> >> "%TASK_XML%"
echo ^<RegistrationInfo^> >> "%TASK_XML%"
echo ^<Description^>Quality Print Service - Automatic Label Printing^</Description^> >> "%TASK_XML%"
echo ^</RegistrationInfo^> >> "%TASK_XML%"
echo ^<Triggers^> >> "%TASK_XML%"
echo ^<BootTrigger^> >> "%TASK_XML%"
echo ^<Enabled^>true^</Enabled^> >> "%TASK_XML%"
echo ^</BootTrigger^> >> "%TASK_XML%"
echo ^</Triggers^> >> "%TASK_XML%"
echo ^<Principals^> >> "%TASK_XML%"
echo ^<Principal id="Author"^> >> "%TASK_XML%"
echo ^<UserId^>S-1-5-18^</UserId^> >> "%TASK_XML%"
echo ^<RunLevel^>HighestAvailable^</RunLevel^> >> "%TASK_XML%"
echo ^</Principal^> >> "%TASK_XML%"
echo ^</Principals^> >> "%TASK_XML%"
echo ^<Settings^> >> "%TASK_XML%"
echo ^<MultipleInstancesPolicy^>IgnoreNew^</MultipleInstancesPolicy^> >> "%TASK_XML%"
echo ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^> >> "%TASK_XML%"
echo ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^> >> "%TASK_XML%"
echo ^<AllowHardTerminate^>true^</AllowHardTerminate^> >> "%TASK_XML%"
echo ^<StartWhenAvailable^>true^</StartWhenAvailable^> >> "%TASK_XML%"
echo ^<RunOnlyIfNetworkAvailable^>false^</RunOnlyIfNetworkAvailable^> >> "%TASK_XML%"
echo ^<AllowStartOnDemand^>true^</AllowStartOnDemand^> >> "%TASK_XML%"
echo ^<Enabled^>true^</Enabled^> >> "%TASK_XML%"
echo ^<Hidden^>false^</Hidden^> >> "%TASK_XML%"
echo ^<RestartOnFailure^> >> "%TASK_XML%"
echo ^<Interval^>PT5M^</Interval^> >> "%TASK_XML%"
echo ^<Count^>3^</Count^> >> "%TASK_XML%"
echo ^</RestartOnFailure^> >> "%TASK_XML%"
echo ^</Settings^> >> "%TASK_XML%"
echo ^<Actions Context="Author"^> >> "%TASK_XML%"
echo ^<Exec^> >> "%TASK_XML%"
echo ^<Command^>"%PYTHON_EXE%"^</Command^> >> "%TASK_XML%"
echo ^<Arguments^>"%PYTHON_SCRIPT%" --service^</Arguments^> >> "%TASK_XML%"
echo ^<WorkingDirectory^>%INSTALL_DIR%^</WorkingDirectory^> >> "%TASK_XML%"
echo ^</Exec^> >> "%TASK_XML%"
echo ^</Actions^> >> "%TASK_XML%"
echo ^</Task^> >> "%TASK_XML%"
schtasks /create /tn "%SERVICE_NAME%" /xml "%TASK_XML%" >nul 2>&1
if %errorLevel% equ 0 (
echo Task Scheduler service created ✅
REM Start task
schtasks /run /tn "%SERVICE_NAME%" >nul 2>&1
if !errorLevel! equ 0 (
echo Task Scheduler service started ✅
set SERVICE_METHOD=TASK_SCHEDULER
goto :service_installed
) else (
echo ⚠️ Task created but failed to start
)
) else (
echo ❌ Task Scheduler creation failed
)
REM Method 3: Startup Script Fallback
echo Installing as Startup Script...
set STARTUP_DIR=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
set STARTUP_SCRIPT=%STARTUP_DIR%\QualityPrintService.bat
echo @echo off > "%STARTUP_SCRIPT%"
echo REM Quality Print Service - Startup Script >> "%STARTUP_SCRIPT%"
echo cd /d "%INSTALL_DIR%" >> "%STARTUP_SCRIPT%"
echo start /min "Quality Print Service" "%PYTHON_EXE%" "%PYTHON_SCRIPT%" --service >> "%STARTUP_SCRIPT%"
if exist "%STARTUP_SCRIPT%" (
echo Startup script created ✅
REM Start immediately
start /min "" "%STARTUP_SCRIPT%"
echo Service started via startup script ✅
set SERVICE_METHOD=STARTUP_SCRIPT
goto :service_installed
)
REM If we get here, all methods failed
echo ❌ All installation methods failed
goto :installation_failed
:service_installed
echo.
REM Verification
echo [8/8] Verifying installation...
echo Waiting for service to start...
timeout /t 5 >nul
REM Test service connection
echo Testing service connection...
for /L %%i in (1,1,10) do (
curl -s http://localhost:8765/health >nul 2>&1
if !errorLevel! equ 0 (
echo Service is responding ✅
goto :success
)
powershell -Command "try { Invoke-WebRequest -Uri 'http://localhost:8765/health' -UseBasicParsing } catch { exit 1 }" >nul 2>&1
if !errorLevel! equ 0 (
echo Service is responding ✅
goto :success
)
echo Attempt %%i failed, retrying...
timeout /t 2 >nul
)
echo ⚠️ Service installed but not responding
goto :partial_success
:success
echo.
echo ========================================
echo INSTALLATION SUCCESSFUL! 🎉
echo ========================================
echo.
echo ✅ Service Method: !SERVICE_METHOD!
echo ✅ Service URL: http://localhost:8765
echo ✅ Health Check: http://localhost:8765/health
echo ✅ Service will start automatically on boot
echo.
echo 📋 NEXT STEPS:
echo 1. Install Chrome extension from 'chrome_extension' folder
echo 2. Test printing from the web application
echo 3. Configure printer settings if needed
echo.
echo 📊 Service Management:
if "!SERVICE_METHOD!"=="SC_SERVICE" (
echo - Start: net start %SERVICE_NAME%
echo - Stop: net stop %SERVICE_NAME%
echo - Status: sc query %SERVICE_NAME%
) else if "!SERVICE_METHOD!"=="TASK_SCHEDULER" (
echo - Start: schtasks /run /tn %SERVICE_NAME%
echo - Stop: schtasks /end /tn %SERVICE_NAME%
echo - Status: schtasks /query /tn %SERVICE_NAME%
) else (
echo - Start: Run startup script manually
echo - Stop: End process in Task Manager
)
echo.
echo 📁 Logs: %LOG_DIR%
echo.
goto :end
:partial_success
echo.
echo ========================================
echo INSTALLATION COMPLETED
echo ========================================
echo.
echo ⚠️ Service installed but verification failed
echo 📋 Manual verification steps:
echo.
echo 1. Check if service is running:
if "!SERVICE_METHOD!"=="SC_SERVICE" (
echo sc query %SERVICE_NAME%
) else if "!SERVICE_METHOD!"=="TASK_SCHEDULER" (
echo schtasks /query /tn %SERVICE_NAME%
) else (
echo Check Task Manager for python.exe process
)
echo.
echo 2. Test service manually:
echo http://localhost:8765/health
echo.
echo 3. Check logs:
echo %LOG_DIR%\service_wrapper.log
echo.
echo 4. Manual start if needed:
if "!SERVICE_METHOD!"=="SC_SERVICE" (
echo net start %SERVICE_NAME%
) else if "!SERVICE_METHOD!"=="TASK_SCHEDULER" (
echo schtasks /run /tn %SERVICE_NAME%
) else (
echo Run: %STARTUP_SCRIPT%
)
echo.
goto :end
:installation_failed
echo.
echo ========================================
echo INSTALLATION FAILED
echo ========================================
echo.
echo ❌ All service installation methods failed
echo.
echo 📋 Troubleshooting steps:
echo 1. Verify Administrator privileges
echo 2. Check Python installation
echo 3. Ensure port 8765 is available
echo 4. Review logs in: %LOG_DIR%
echo 5. Try manual service start
echo.
echo 🔧 Manual installation:
echo cd /d "%INSTALL_DIR%"
echo "%PYTHON_EXE%" "%PYTHON_SCRIPT%" --standalone
echo.
pause
exit /b 1
:end
echo Press any key to exit...
pause >nul

View File

@@ -1,243 +0,0 @@
@echo off
setlocal enabledelayedexpansion
echo ========================================
echo Quality Label Print Service Installer
echo Complete Self-Contained Version
echo ========================================
echo.
REM Check for administrator privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
echo ERROR: This installer requires Administrator privileges.
echo Please right-click this file and select "Run as administrator"
echo.
pause
exit /b 1
)
echo [1/6] Administrator privileges confirmed ✓
echo.
REM Get current directory and set variables
set CURRENT_DIR=%~dp0
set SERVICE_NAME=QualityPrintService
set SERVICE_DISPLAY_NAME=Quality Label Print Service
set INSTALL_DIR=C:\QualityPrintService
set PYTHON_SCRIPT=%INSTALL_DIR%\print_service_complete.py
set LOG_DIR=%USERPROFILE%\PrintService\logs
echo [2/6] Checking Python installation...
REM Check if Python is available
python --version >nul 2>&1
if %errorLevel% neq 0 (
echo WARNING: Python not found in PATH
echo.
echo Installing portable Python interpreter...
REM Download portable Python (this would need to be included in the zip)
if exist "%CURRENT_DIR%python_portable" (
echo Using included portable Python ✓
set PYTHON_EXE=%CURRENT_DIR%python_portable\python.exe
) else (
echo ERROR: Portable Python not found in package
echo Please ensure python_portable folder is included
pause
exit /b 1
)
) else (
echo Python found in system PATH ✓
set PYTHON_EXE=python
)
echo [3/6] Creating installation directories...
REM Create installation directory
if not exist "%INSTALL_DIR%" (
mkdir "%INSTALL_DIR%"
echo Created: %INSTALL_DIR%
)
REM Create log directory
if not exist "%LOG_DIR%" (
mkdir "%LOG_DIR%"
echo Created: %LOG_DIR%
)
echo [4/6] Installing service files...
REM Copy service files
copy "%CURRENT_DIR%print_service_complete.py" "%INSTALL_DIR%\" >nul
if %errorLevel% equ 0 (
echo Copied print service script ✓
) else (
echo ERROR: Failed to copy service script
pause
exit /b 1
)
REM Copy additional files if they exist
if exist "%CURRENT_DIR%requirements_complete.txt" (
copy "%CURRENT_DIR%requirements_complete.txt" "%INSTALL_DIR%\" >nul
echo Copied requirements file ✓
)
REM Copy portable Python if included
if exist "%CURRENT_DIR%python_portable" (
echo Copying portable Python interpreter...
xcopy "%CURRENT_DIR%python_portable" "%INSTALL_DIR%\python_portable\" /E /I /H /Y >nul
if %errorLevel% equ 0 (
echo Portable Python installed ✓
set PYTHON_EXE=%INSTALL_DIR%\python_portable\python.exe
)
)
echo [5/6] Installing Windows service...
REM Remove existing service if it exists
sc query "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo Stopping existing service...
sc stop "%SERVICE_NAME%" >nul 2>&1
timeout /t 3 >nul
echo Removing existing service...
sc delete "%SERVICE_NAME%" >nul 2>&1
timeout /t 2 >nul
)
REM Try to install with NSSM first (if available)
if exist "%CURRENT_DIR%nssm.exe" (
echo Installing with NSSM (Non-Sucking Service Manager)...
"%CURRENT_DIR%nssm.exe" install "%SERVICE_NAME%" "%PYTHON_EXE%" "%PYTHON_SCRIPT%"
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" DisplayName "%SERVICE_DISPLAY_NAME%"
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" Description "Quality Label Printing Service for Windows"
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" Start SERVICE_AUTO_START
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" AppStdout "%LOG_DIR%\service_output.log"
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" AppStderr "%LOG_DIR%\service_error.log"
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" AppRotateFiles 1
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" AppRotateOnline 1
"%CURRENT_DIR%nssm.exe" set "%SERVICE_NAME%" AppRotateBytes 1048576
echo Windows service installed with NSSM ✓
) else (
echo Installing with Windows SC command (Enhanced Service Wrapper)...
REM Copy service wrapper
copy "%CURRENT_DIR%service_wrapper.py" "%INSTALL_DIR%\" >nul
if %errorLevel% neq 0 (
echo WARNING: Service wrapper not found, creating basic wrapper...
)
REM Create enhanced service wrapper batch file
set WRAPPER_BAT=%INSTALL_DIR%\service_wrapper.bat
echo @echo off > "%WRAPPER_BAT%"
echo REM Windows Print Service Wrapper - Fixed for Error 1053 >> "%WRAPPER_BAT%"
echo cd /d "%INSTALL_DIR%" >> "%WRAPPER_BAT%"
echo. >> "%WRAPPER_BAT%"
echo REM Check if Python service wrapper exists >> "%WRAPPER_BAT%"
echo if exist "%INSTALL_DIR%\service_wrapper.py" ( >> "%WRAPPER_BAT%"
echo echo Starting service with wrapper... >> "%WRAPPER_BAT%"
echo "%PYTHON_EXE%" "%INSTALL_DIR%\service_wrapper.py" >> "%WRAPPER_BAT%"
echo ^) else ( >> "%WRAPPER_BAT%"
echo echo Starting service directly... >> "%WRAPPER_BAT%"
echo "%PYTHON_EXE%" "%PYTHON_SCRIPT%" --service >> "%WRAPPER_BAT%"
echo ^) >> "%WRAPPER_BAT%"
REM Install service using sc command with enhanced wrapper
sc create "%SERVICE_NAME%" binPath= "\"%WRAPPER_BAT%\"" DisplayName= "%SERVICE_DISPLAY_NAME%" start= auto
if %errorLevel% equ 0 (
echo Windows service installed with Enhanced SC Wrapper ✓
) else (
echo ERROR: Failed to install Windows service
echo Trying scheduled task fallback...
goto :install_scheduled_task
)
)
REM Configure service recovery options
echo Configuring service recovery options...
sc failure "%SERVICE_NAME%" reset= 86400 actions= restart/5000/restart/5000/restart/5000 >nul 2>&1
goto :start_service
:install_scheduled_task
echo [5/6] Installing as scheduled task (fallback)...
REM Create scheduled task as fallback
schtasks /create /tn "%SERVICE_NAME%" /tr "\"%PYTHON_EXE%\" \"%PYTHON_SCRIPT%\"" /sc onstart /ru SYSTEM /f >nul 2>&1
if %errorLevel% equ 0 (
echo Scheduled task installed ✓
REM Start the task
schtasks /run /tn "%SERVICE_NAME%" >nul 2>&1
echo Scheduled task started ✓
) else (
echo ERROR: Failed to install scheduled task
pause
exit /b 1
)
goto :install_chrome_extension
:start_service
echo [6/6] Starting service...
REM Start the service
sc start "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo Service started successfully ✓
) else (
echo WARNING: Service may not have started properly
echo This is normal on first install - the service will auto-start on next boot
)
:install_chrome_extension
echo.
echo ========================================
echo Installation Complete! ✓
echo ========================================
echo.
echo Service Details:
echo Name: %SERVICE_NAME%
echo Location: %INSTALL_DIR%
echo Logs: %LOG_DIR%
echo URL: http://localhost:8765
echo.
REM Test service connectivity
echo Testing service connectivity...
timeout /t 3 >nul
powershell -Command "try { $response = Invoke-RestMethod -Uri 'http://localhost:8765/health' -TimeoutSec 10; if ($response.status -eq 'healthy') { Write-Host 'Service is responding ✓' -ForegroundColor Green } else { Write-Host 'Service responded but may have issues' -ForegroundColor Yellow } } catch { Write-Host 'Service not yet responding (this is normal on first install)' -ForegroundColor Yellow }"
echo.
echo Next Steps:
echo 1. Install Chrome Extension:
echo - Open Chrome and go to chrome://extensions/
echo - Enable 'Developer mode'
echo - Click 'Load unpacked' and select the chrome_extension folder
echo.
echo 2. Test the installation:
echo - Visit: http://localhost:8765/health
echo - Expected response: {"status": "healthy"}
echo.
echo 3. The service will automatically start with Windows
echo.
if exist "%CURRENT_DIR%chrome_extension\" (
echo Opening Chrome extension folder...
explorer "%CURRENT_DIR%chrome_extension"
)
echo Installation completed successfully!
echo The Quality Print Service is now ready to use.
echo.
pause

View File

@@ -1,666 +0,0 @@
"""
Windows Print Service for Quality Label Printing
Receives PDFs from Chrome extension and prints them page by page
Windows-compatible version with comprehensive dependency support
"""
import os
import sys
import json
import logging
import tempfile
import subprocess
import platform
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
import urllib.request
from datetime import datetime
import threading
import time
import shutil
import winreg
from pathlib import Path
# Windows-specific imports with fallbacks
try:
import win32print
import win32api
import win32con
import win32ui
import win32gui
WINDOWS_PRINTING_AVAILABLE = True
except ImportError:
print("Warning: pywin32 not available. Some Windows-specific features may not work.")
WINDOWS_PRINTING_AVAILABLE = False
# PDF processing imports with fallbacks
try:
from PyPDF2 import PdfReader, PdfWriter
PYPDF2_AVAILABLE = True
except ImportError:
try:
from pypdf import PdfReader, PdfWriter
PYPDF2_AVAILABLE = True
except ImportError:
print("Warning: PDF processing library not available. Install PyPDF2 or pypdf.")
PYPDF2_AVAILABLE = False
# Advanced PDF processing (optional)
try:
import fitz # PyMuPDF
PYMUPDF_AVAILABLE = True
except ImportError:
PYMUPDF_AVAILABLE = False
# Image processing for PDF conversion
try:
from PIL import Image
from pdf2image import convert_from_path
IMAGE_PROCESSING_AVAILABLE = True
except ImportError:
IMAGE_PROCESSING_AVAILABLE = False
# HTTP requests
try:
import requests
REQUESTS_AVAILABLE = True
except ImportError:
REQUESTS_AVAILABLE = False
# Configure logging
log_dir = os.path.join(os.path.expanduser("~"), "QualityLabelPrinting", "logs")
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, "print_service.log")
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(log_file),
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
class PrintServiceHandler(BaseHTTPRequestHandler):
def log_message(self, format, *args):
"""Override to use our logger instead of stderr"""
logger.info(f"{self.address_string()} - {format % args}")
def do_GET(self):
"""Handle GET requests"""
try:
parsed_path = urlparse(self.path)
path = parsed_path.path
if path == '/health':
self.handle_health_check()
elif path == '/printers':
self.handle_get_printers()
elif path == '/status':
self.handle_service_status()
else:
self.send_error(404, "Endpoint not found")
except Exception as e:
logger.error(f"Error handling GET request: {e}")
self.send_error(500, str(e))
def do_POST(self):
"""Handle POST requests"""
try:
parsed_path = urlparse(self.path)
path = parsed_path.path
if path == '/print_pdf':
self.handle_print_pdf()
elif path == '/print_url':
self.handle_print_url()
else:
self.send_error(404, "Endpoint not found")
except Exception as e:
logger.error(f"Error handling POST request: {e}")
self.send_error(500, str(e))
def handle_health_check(self):
"""Health check endpoint"""
response = {
"status": "healthy",
"service": "Quality Label Print Service",
"version": "2.0.0",
"platform": "Windows",
"timestamp": datetime.now().isoformat(),
"capabilities": ["pdf_printing", "page_by_page", "printer_selection"]
}
self.send_json_response(200, response)
def handle_get_printers(self):
"""Get available printers"""
try:
printers = self.get_available_printers()
response = {
"success": True,
"printers": printers,
"count": len(printers)
}
self.send_json_response(200, response)
except Exception as e:
logger.error(f"Error getting printers: {e}")
response = {
"success": False,
"error": str(e),
"printers": []
}
self.send_json_response(500, response)
def handle_service_status(self):
"""Service status information"""
response = {
"service_name": "Quality Label Print Service",
"running": True,
"uptime": "Available",
"last_print_job": getattr(self.server, 'last_print_time', 'Never'),
"total_jobs": getattr(self.server, 'total_jobs', 0)
}
self.send_json_response(200, response)
def handle_print_pdf(self):
"""Handle PDF printing requests"""
try:
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
data = json.loads(post_data.decode('utf-8'))
logger.info(f"Received print request: {data}")
# Extract request data
pdf_url = data.get('pdf_url')
printer_name = data.get('printer_name', 'default')
order_id = data.get('order_id')
prod_order = data.get('prod_order')
quantity = data.get('quantity')
if not pdf_url:
raise ValueError("PDF URL is required")
# Download PDF
logger.info(f"Downloading PDF from: {pdf_url}")
pdf_path = self.download_pdf(pdf_url)
# Print PDF page by page
logger.info(f"Printing PDF to: {printer_name}")
print_result = self.print_pdf_pages(pdf_path, printer_name)
# Update service stats
self.server.last_print_time = datetime.now().isoformat()
self.server.total_jobs = getattr(self.server, 'total_jobs', 0) + 1
# Clean up temporary file
try:
os.unlink(pdf_path)
except:
pass
response = {
"success": True,
"message": f"PDF printed successfully to {printer_name}",
"order_id": order_id,
"prod_order": prod_order,
"quantity": quantity,
"pages_printed": print_result.get('pages', 0),
"printer_used": print_result.get('printer', printer_name),
"method": "windows_service_page_by_page"
}
logger.info(f"Print job completed: {response}")
self.send_json_response(200, response)
except Exception as e:
logger.error(f"Error printing PDF: {e}")
response = {
"success": False,
"error": str(e),
"method": "windows_service_error"
}
self.send_json_response(500, response)
def handle_print_url(self):
"""Alternative endpoint that accepts PDF URL and prints it"""
try:
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
data = json.loads(post_data.decode('utf-8'))
# Same logic as handle_print_pdf
self.handle_print_pdf()
except Exception as e:
logger.error(f"Error in print_url endpoint: {e}")
self.send_error(500, str(e))
def download_pdf(self, pdf_url):
"""Download PDF from URL to temporary file"""
try:
# Create temporary file
temp_dir = tempfile.gettempdir()
temp_file = tempfile.NamedTemporaryFile(
suffix='.pdf',
prefix='quality_label_',
delete=False,
dir=temp_dir
)
temp_path = temp_file.name
temp_file.close()
logger.info(f"Downloading PDF to: {temp_path}")
# Download the PDF
urllib.request.urlretrieve(pdf_url, temp_path)
logger.info(f"PDF downloaded successfully: {os.path.getsize(temp_path)} bytes")
return temp_path
except Exception as e:
logger.error(f"Error downloading PDF: {e}")
raise
def print_pdf_pages(self, pdf_path, printer_name):
"""Print PDF page by page using Windows printing"""
try:
logger.info(f"Starting page-by-page printing of: {pdf_path}")
# Method 1: Use Adobe Reader command line (if available)
adobe_result = self.try_adobe_print(pdf_path, printer_name)
if adobe_result['success']:
return adobe_result
# Method 2: Use SumatraPDF (lightweight, good for automation)
sumatra_result = self.try_sumatra_print(pdf_path, printer_name)
if sumatra_result['success']:
return sumatra_result
# Method 3: Use Windows PowerShell
powershell_result = self.try_powershell_print(pdf_path, printer_name)
if powershell_result['success']:
return powershell_result
# Method 4: Use Python PDF library + Windows printing
python_result = self.try_python_print(pdf_path, printer_name)
return python_result
except Exception as e:
logger.error(f"Error printing PDF pages: {e}")
return {"success": False, "error": str(e), "pages": 0}
def try_adobe_print(self, pdf_path, printer_name):
"""Try printing with Adobe Reader"""
try:
# Common Adobe Reader paths
adobe_paths = [
r"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",
r"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",
r"C:\Program Files\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
]
adobe_path = None
for path in adobe_paths:
if os.path.exists(path):
adobe_path = path
break
if not adobe_path:
return {"success": False, "reason": "Adobe Reader not found"}
# Adobe command line printing
if printer_name == 'default':
cmd = [adobe_path, "/t", pdf_path]
else:
cmd = [adobe_path, "/t", pdf_path, printer_name]
logger.info(f"Running Adobe print command: {cmd}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
logger.info("Adobe Reader print successful")
return {
"success": True,
"method": "adobe_reader",
"printer": printer_name,
"pages": "unknown" # Adobe doesn't return page count
}
else:
logger.warning(f"Adobe print failed: {result.stderr}")
return {"success": False, "reason": f"Adobe error: {result.stderr}"}
except Exception as e:
logger.warning(f"Adobe print method failed: {e}")
return {"success": False, "reason": str(e)}
def try_sumatra_print(self, pdf_path, printer_name):
"""Try printing with SumatraPDF"""
try:
# SumatraPDF is lightweight and good for automation
sumatra_paths = [
r"C:\Program Files\SumatraPDF\SumatraPDF.exe",
r"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe"
]
sumatra_path = None
for path in sumatra_paths:
if os.path.exists(path):
sumatra_path = path
break
if not sumatra_path:
return {"success": False, "reason": "SumatraPDF not found"}
# SumatraPDF command line printing
if printer_name == 'default':
cmd = [sumatra_path, "-print-to-default", pdf_path]
else:
cmd = [sumatra_path, "-print-to", printer_name, pdf_path]
logger.info(f"Running SumatraPDF command: {cmd}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
logger.info("SumatraPDF print successful")
return {
"success": True,
"method": "sumatra_pdf",
"printer": printer_name,
"pages": "unknown"
}
else:
logger.warning(f"SumatraPDF print failed: {result.stderr}")
return {"success": False, "reason": f"SumatraPDF error: {result.stderr}"}
except Exception as e:
logger.warning(f"SumatraPDF print method failed: {e}")
return {"success": False, "reason": str(e)}
def try_powershell_print(self, pdf_path, printer_name):
"""Try printing with PowerShell"""
try:
# PowerShell script to print PDF
if printer_name == 'default':
ps_script = f'''
Add-Type -AssemblyName System.Drawing
$pdf = New-Object System.Drawing.Printing.PrintDocument
$pdf.DocumentName = "{os.path.basename(pdf_path)}"
Start-Process -FilePath "{pdf_path}" -Verb Print -Wait
'''
else:
ps_script = f'''
Add-Type -AssemblyName System.Drawing
$pdf = New-Object System.Drawing.Printing.PrintDocument
$pdf.PrinterSettings.PrinterName = "{printer_name}"
$pdf.DocumentName = "{os.path.basename(pdf_path)}"
Start-Process -FilePath "{pdf_path}" -Verb Print -Wait
'''
# Execute PowerShell
cmd = ["powershell", "-Command", ps_script]
logger.info("Running PowerShell print command")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=45)
if result.returncode == 0:
logger.info("PowerShell print successful")
return {
"success": True,
"method": "powershell",
"printer": printer_name,
"pages": "unknown"
}
else:
logger.warning(f"PowerShell print failed: {result.stderr}")
return {"success": False, "reason": f"PowerShell error: {result.stderr}"}
except Exception as e:
logger.warning(f"PowerShell print method failed: {e}")
return {"success": False, "reason": str(e)}
def try_python_print(self, pdf_path, printer_name):
"""Try printing with Python libraries"""
try:
# This would require additional libraries like win32print
# For now, return a fallback method
logger.info("Python print method - using default system print")
# Use Windows default print handler
if printer_name == 'default':
os.startfile(pdf_path, "print")
else:
# More complex implementation would be needed for specific printer
os.startfile(pdf_path, "print")
return {
"success": True,
"method": "python_system_print",
"printer": printer_name,
"pages": "unknown"
}
except Exception as e:
logger.error(f"Python print method failed: {e}")
return {"success": False, "reason": str(e)}
def get_available_printers(self):
"""Get list of available printers on Windows with comprehensive detection"""
printers = []
# Method 1: Windows API (most reliable if pywin32 is available)
if WINDOWS_PRINTING_AVAILABLE:
try:
printer_info = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)
for printer in printer_info:
printer_name = printer[2] # Printer name is at index 2
# Check if this is the default printer
try:
default_printer = win32print.GetDefaultPrinter()
is_default = (printer_name == default_printer)
except:
is_default = False
printers.append({
"name": printer_name,
"display_name": printer_name,
"is_default": is_default,
"status": "available",
"type": "Windows API"
})
logger.info(f"Found {len(printers)} printers via Windows API")
return printers
except Exception as e:
logger.warning(f"Windows API printer enumeration failed: {e}")
# Method 2: PowerShell (good fallback)
if not printers:
try:
cmd = ["powershell", "-Command", "Get-Printer | Select-Object Name,Default | ConvertTo-Json"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=15, shell=True)
if result.returncode == 0 and result.stdout.strip():
try:
printers_data = json.loads(result.stdout)
if not isinstance(printers_data, list):
printers_data = [printers_data] # Single printer case
for printer in printers_data:
printers.append({
"name": printer.get("Name", "Unknown"),
"display_name": printer.get("Name", "Unknown"),
"is_default": printer.get("Default", False),
"status": "available",
"type": "PowerShell"
})
logger.info(f"Found {len(printers)} printers via PowerShell")
except json.JSONDecodeError as e:
logger.warning(f"Failed to parse PowerShell printer JSON: {e}")
except Exception as e:
logger.warning(f"PowerShell printer enumeration failed: {e}")
# Method 3: WMIC command (older Windows compatibility)
if not printers:
try:
result = subprocess.run(['wmic', 'printer', 'get', 'name', '/format:csv'],
capture_output=True, text=True, shell=True, timeout=10)
if result.returncode == 0:
lines = result.stdout.strip().split('\n')[1:] # Skip header
for line in lines:
if line.strip() and ',' in line:
parts = line.split(',')
if len(parts) >= 2 and parts[1].strip():
printer_name = parts[1].strip()
printers.append({
"name": printer_name,
"display_name": printer_name,
"is_default": False,
"status": "available",
"type": "WMIC"
})
logger.info(f"Found {len(printers)} printers via WMIC")
except Exception as e:
logger.warning(f"WMIC printer enumeration failed: {e}")
# Method 4: Registry search (comprehensive fallback)
if not printers:
try:
import winreg
reg_path = r"SYSTEM\CurrentControlSet\Control\Print\Printers"
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path) as key:
i = 0
while True:
try:
printer_name = winreg.EnumKey(key, i)
printers.append({
"name": printer_name,
"display_name": printer_name,
"is_default": False,
"status": "available",
"type": "Registry"
})
i += 1
except OSError:
break
logger.info(f"Found {len(printers)} printers via Registry")
except Exception as e:
logger.warning(f"Registry printer enumeration failed: {e}")
# Fallback: Add common Windows printers
if not printers:
common_printers = [
("Microsoft Print to PDF", True),
("Microsoft XPS Document Writer", False),
("OneNote for Windows 10", False),
("Fax", False)
]
for printer_name, is_default in common_printers:
printers.append({
"name": printer_name,
"display_name": f"{printer_name} (Built-in)",
"is_default": is_default,
"status": "available",
"type": "Built-in"
})
logger.info(f"Using {len(printers)} built-in printer options")
# Ensure we have at least one default option
if not printers:
printers.append({
"name": "default",
"display_name": "System Default Printer",
"is_default": True,
"status": "available",
"type": "Fallback"
})
logger.info(f"Total available printers: {len(printers)}")
return printers
def send_json_response(self, status_code, data):
"""Send JSON response"""
self.send_response(status_code)
self.send_header('Content-type', 'application/json')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
self.end_headers()
json_data = json.dumps(data, indent=2)
self.wfile.write(json_data.encode('utf-8'))
def do_OPTIONS(self):
"""Handle CORS preflight requests"""
self.send_response(200)
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
self.end_headers()
class PrintService:
def __init__(self, port=8765):
self.port = port
self.server = None
self.running = False
def start(self):
"""Start the print service"""
try:
logger.info(f"Starting Quality Label Print Service on port {self.port}")
self.server = HTTPServer(('localhost', self.port), PrintServiceHandler)
self.server.total_jobs = 0
self.server.last_print_time = None
logger.info(f"Print service running at http://localhost:{self.port}")
logger.info("Available endpoints:")
logger.info(" GET /health - Health check")
logger.info(" GET /printers - List available printers")
logger.info(" GET /status - Service status")
logger.info(" POST /print_pdf - Print PDF from URL")
self.running = True
self.server.serve_forever()
except KeyboardInterrupt:
logger.info("Service stopped by user")
except Exception as e:
logger.error(f"Service error: {e}")
finally:
self.stop()
def stop(self):
"""Stop the print service"""
if self.server:
logger.info("Shutting down print service...")
self.server.shutdown()
self.server.server_close()
self.running = False
if __name__ == "__main__":
service = PrintService(port=8765)
try:
service.start()
except KeyboardInterrupt:
print("\nService stopped by user")
except Exception as e:
print(f"Service failed to start: {e}")
logger.error(f"Service failed to start: {e}")

View File

@@ -1,642 +0,0 @@
#!/usr/bin/env python3
"""
Windows Print Service - Complete Self-Contained Version
Fixed for Windows Service Error 1053 - Proper Service Implementation
"""
import sys
import os
import json
import logging
import subprocess
import tempfile
import shutil
import time
import signal
from datetime import datetime
from pathlib import Path
import threading
import webbrowser
from urllib.parse import urlparse, unquote
import urllib.request
import zipfile
# Built-in HTTP server modules
from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import ThreadingMixIn
# Global variables for service control
service_running = True
httpd_server = None
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
daemon_threads = True
allow_reuse_address = True
class PrintServiceHandler(BaseHTTPRequestHandler):
"""HTTP request handler for the print service."""
def __init__(self, *args, **kwargs):
self.temp_dir = tempfile.mkdtemp(prefix="print_service_")
super().__init__(*args, **kwargs)
def log_message(self, format, *args):
"""Override default logging to use our logger."""
logging.info(f"{self.client_address[0]} - {format % args}")
def do_GET(self):
"""Handle GET requests."""
try:
if self.path == '/health':
self.send_health_response()
elif self.path == '/printers':
self.send_printers_response()
elif self.path == '/status':
self.send_status_response()
else:
self.send_error(404, "Endpoint not found")
except Exception as e:
logging.error(f"GET request error: {e}")
self.send_error(500, str(e))
def do_POST(self):
"""Handle POST requests."""
try:
if self.path == '/print_pdf':
self.handle_print_pdf()
else:
self.send_error(404, "Endpoint not found")
except Exception as e:
logging.error(f"POST request error: {e}")
self.send_error(500, str(e))
def send_health_response(self):
"""Send health check response."""
response = {
"status": "healthy",
"service": "Windows Print Service",
"version": "1.0.0",
"timestamp": datetime.now().isoformat(),
"platform": sys.platform,
"python_version": sys.version,
"temp_dir": self.temp_dir
}
self.send_json_response(response)
def send_printers_response(self):
"""Send available printers list."""
printers = self.get_available_printers()
response = {
"success": True,
"printers": printers,
"count": len(printers),
"timestamp": datetime.now().isoformat()
}
self.send_json_response(response)
def send_status_response(self):
"""Send service status."""
response = {
"service_name": "Windows Print Service",
"status": "running",
"uptime": time.time() - start_time,
"requests_handled": getattr(self.server, 'request_count', 0),
"last_activity": datetime.now().isoformat()
}
self.send_json_response(response)
def handle_print_pdf(self):
"""Handle PDF printing request."""
try:
# Get content length
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length).decode('utf-8')
# Parse JSON data
try:
data = json.loads(post_data)
except json.JSONDecodeError:
self.send_error(400, "Invalid JSON data")
return
pdf_url = data.get('pdf_url')
printer_name = data.get('printer_name', 'default')
if not pdf_url:
self.send_error(400, "Missing pdf_url parameter")
return
logging.info(f"Print request - URL: {pdf_url}, Printer: {printer_name}")
# Download and print PDF
result = self.download_and_print_pdf(pdf_url, printer_name)
if result['success']:
response = {
"success": True,
"message": "PDF sent to printer successfully",
"printer": printer_name,
"method": result.get('method', 'unknown'),
"timestamp": datetime.now().isoformat()
}
else:
response = {
"success": False,
"error": result.get('error', 'Unknown error'),
"timestamp": datetime.now().isoformat()
}
self.send_json_response(response)
except Exception as e:
logging.error(f"Print PDF error: {e}")
response = {
"success": False,
"error": str(e),
"timestamp": datetime.now().isoformat()
}
self.send_json_response(response)
def download_and_print_pdf(self, pdf_url, printer_name):
"""Download PDF and send to printer."""
try:
# Create unique filename
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
pdf_filename = f"print_job_{timestamp}.pdf"
pdf_path = os.path.join(self.temp_dir, pdf_filename)
# Download PDF
logging.info(f"Downloading PDF from: {pdf_url}")
urllib.request.urlretrieve(pdf_url, pdf_path)
if not os.path.exists(pdf_path):
return {"success": False, "error": "Failed to download PDF"}
logging.info(f"PDF downloaded to: {pdf_path}")
# Try different printing methods
print_methods = [
self.print_with_adobe_reader,
self.print_with_sumatra_pdf,
self.print_with_powershell,
self.print_with_edge,
self.print_with_system_default
]
for method in print_methods:
try:
result = method(pdf_path, printer_name)
if result['success']:
# Clean up downloaded file after successful print
try:
os.remove(pdf_path)
except:
pass
return result
except Exception as e:
logging.warning(f"Print method {method.__name__} failed: {e}")
continue
return {"success": False, "error": "All printing methods failed"}
except Exception as e:
logging.error(f"Download and print error: {e}")
return {"success": False, "error": str(e)}
def print_with_adobe_reader(self, pdf_path, printer_name):
"""Print using Adobe Reader command line."""
try:
# Common Adobe Reader paths
adobe_paths = [
r"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",
r"C:\Program Files\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",
r"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe",
r"C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.exe"
]
adobe_exe = None
for path in adobe_paths:
if os.path.exists(path):
adobe_exe = path
break
if not adobe_exe:
return {"success": False, "error": "Adobe Reader not found"}
# Build command
if printer_name == 'default':
cmd = [adobe_exe, "/t", pdf_path]
else:
cmd = [adobe_exe, "/t", pdf_path, printer_name]
logging.info(f"Adobe Reader command: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
return {"success": True, "method": "Adobe Reader"}
else:
return {"success": False, "error": f"Adobe Reader failed: {result.stderr}"}
except subprocess.TimeoutExpired:
return {"success": False, "error": "Adobe Reader timeout"}
except Exception as e:
return {"success": False, "error": f"Adobe Reader error: {e}"}
def print_with_sumatra_pdf(self, pdf_path, printer_name):
"""Print using SumatraPDF."""
try:
# Common SumatraPDF paths
sumatra_paths = [
r"C:\Program Files\SumatraPDF\SumatraPDF.exe",
r"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe",
os.path.join(os.environ.get('LOCALAPPDATA', ''), 'SumatraPDF', 'SumatraPDF.exe')
]
sumatra_exe = None
for path in sumatra_paths:
if os.path.exists(path):
sumatra_exe = path
break
if not sumatra_exe:
return {"success": False, "error": "SumatraPDF not found"}
# Build command
if printer_name == 'default':
cmd = [sumatra_exe, "-print-dialog", pdf_path]
else:
cmd = [sumatra_exe, "-print-to", printer_name, pdf_path]
logging.info(f"SumatraPDF command: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
return {"success": True, "method": "SumatraPDF"}
except subprocess.TimeoutExpired:
return {"success": False, "error": "SumatraPDF timeout"}
except Exception as e:
return {"success": False, "error": f"SumatraPDF error: {e}"}
def print_with_powershell(self, pdf_path, printer_name):
"""Print using PowerShell."""
try:
if printer_name == 'default':
powershell_cmd = f'''
$pdf = "{pdf_path}"
Start-Process -FilePath $pdf -Verb Print -WindowStyle Hidden
'''
else:
# Use specific printer with PowerShell
powershell_cmd = f'''
$printer = "{printer_name}"
$pdf = "{pdf_path}"
$shell = New-Object -ComObject Shell.Application
$file = $shell.NameSpace((Get-Item $pdf).DirectoryName).ParseName((Get-Item $pdf).Name)
$file.InvokeVerb("print")
'''
cmd = ["powershell", "-Command", powershell_cmd]
logging.info("PowerShell print command executed")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
return {"success": True, "method": "PowerShell"}
except subprocess.TimeoutExpired:
return {"success": False, "error": "PowerShell timeout"}
except Exception as e:
return {"success": False, "error": f"PowerShell error: {e}"}
def print_with_edge(self, pdf_path, printer_name):
"""Print using Microsoft Edge."""
try:
# Convert to file URL
file_url = f"file:///{pdf_path.replace(os.sep, '/')}"
cmd = ["msedge", "--print-to-pdf", "--run-all-compositor-stages-before-draw", file_url]
logging.info("Edge print command executed")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
return {"success": True, "method": "Microsoft Edge"}
except subprocess.TimeoutExpired:
return {"success": False, "error": "Edge timeout"}
except Exception as e:
return {"success": False, "error": f"Edge error: {e}"}
def print_with_system_default(self, pdf_path, printer_name):
"""Print using system default application."""
try:
# Use Windows shell to open and print
cmd = ["cmd", "/c", "start", "/wait", pdf_path]
logging.info("System default print executed")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
return {"success": True, "method": "System Default"}
except subprocess.TimeoutExpired:
return {"success": False, "error": "System default timeout"}
except Exception as e:
return {"success": False, "error": f"System default error: {e}"}
def get_available_printers(self):
"""Get list of available printers using Windows commands."""
try:
printers = []
# Method 1: Use PowerShell to get printers
try:
cmd = ["powershell", "-Command", "Get-Printer | Select-Object Name, Type, PrinterStatus | ConvertTo-Json"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
if result.returncode == 0:
printer_data = json.loads(result.stdout)
if isinstance(printer_data, list):
for printer in printer_data:
printers.append({
"name": printer.get("Name", "Unknown"),
"type": printer.get("Type", "Unknown"),
"status": printer.get("PrinterStatus", "Unknown"),
"is_default": False
})
else:
printers.append({
"name": printer_data.get("Name", "Unknown"),
"type": printer_data.get("Type", "Unknown"),
"status": printer_data.get("PrinterStatus", "Unknown"),
"is_default": False
})
except:
pass
# Method 2: Use wmic command as fallback
if not printers:
try:
cmd = ["wmic", "printer", "get", "name,default", "/format:csv"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
if result.returncode == 0:
lines = result.stdout.strip().split('\n')[1:] # Skip header
for line in lines:
parts = line.split(',')
if len(parts) >= 3:
printer_name = parts[2].strip()
is_default = parts[1].strip().lower() == 'true'
if printer_name:
printers.append({
"name": printer_name,
"type": "Windows Printer",
"status": "Available",
"is_default": is_default
})
except:
pass
# Add default fallback printers
if not printers:
printers = [
{"name": "Microsoft Print to PDF", "type": "Virtual", "status": "Available", "is_default": False},
{"name": "Default Printer", "type": "System", "status": "Available", "is_default": True}
]
return printers
except Exception as e:
logging.error(f"Error getting printers: {e}")
return [{"name": "Default Printer", "type": "System", "status": "Unknown", "is_default": True}]
def send_json_response(self, data, status_code=200):
"""Send JSON response."""
self.send_response(status_code)
self.send_header('Content-type', 'application/json')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
self.end_headers()
json_response = json.dumps(data, indent=2)
self.wfile.write(json_response.encode('utf-8'))
def setup_logging():
"""Setup logging configuration."""
log_dir = os.path.join(os.path.expanduser("~"), "PrintService", "logs")
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, f"print_service_{datetime.now().strftime('%Y%m%d')}.log")
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(log_file),
logging.StreamHandler(sys.stdout)
]
)
def create_windows_service():
"""Create Windows service registration script."""
service_script = '''
@echo off
echo Installing Windows Print Service...
REM Check for administrator privileges
net session >nul 2>&1
if %errorLevel% == 0 (
echo Administrator privileges confirmed.
) else (
echo This script requires administrator privileges.
echo Please right-click and "Run as administrator"
pause
exit /b 1
)
REM Get current directory
set CURRENT_DIR=%~dp0
REM Install service using sc command
sc create "WindowsPrintService" binPath= "%CURRENT_DIR%print_service_complete.exe" DisplayName= "Windows Print Service" start= auto
REM Configure service recovery options
sc failure "WindowsPrintService" reset= 86400 actions= restart/5000/restart/5000/restart/5000
REM Start the service
sc start "WindowsPrintService"
echo Windows Print Service installed and started successfully!
echo Service will auto-start with Windows.
echo.
echo Test the service: http://localhost:8765/health
pause
'''
with open('install_service_complete.bat', 'w') as f:
f.write(service_script)
def signal_handler(signum, frame):
"""Handle shutdown signals gracefully."""
global service_running, httpd_server
logging.info(f"Received signal {signum}, shutting down gracefully...")
service_running = False
if httpd_server:
# Shutdown server in a separate thread to avoid blocking
def shutdown_server():
try:
httpd_server.shutdown()
httpd_server.server_close()
except Exception as e:
logging.error(f"Error during server shutdown: {e}")
shutdown_thread = threading.Thread(target=shutdown_server)
shutdown_thread.daemon = True
shutdown_thread.start()
shutdown_thread.join(timeout=5)
logging.info("Service shutdown complete")
sys.exit(0)
def setup_signal_handlers():
"""Setup signal handlers for graceful shutdown."""
if hasattr(signal, 'SIGTERM'):
signal.signal(signal.SIGTERM, signal_handler)
if hasattr(signal, 'SIGINT'):
signal.signal(signal.SIGINT, signal_handler)
if hasattr(signal, 'SIGBREAK'): # Windows specific
signal.signal(signal.SIGBREAK, signal_handler)
def main():
"""Main service function with proper Windows service support."""
global start_time, service_running, httpd_server
start_time = time.time()
# Setup logging first
setup_logging()
logging.info("=== Starting Windows Print Service (Complete Version) ===")
logging.info(f"Python version: {sys.version}")
logging.info(f"Platform: {sys.platform}")
logging.info(f"Process ID: {os.getpid()}")
logging.info(f"Command line args: {sys.argv}")
# Setup signal handlers for graceful shutdown
setup_signal_handlers()
# Determine run mode
run_mode = "standalone"
if len(sys.argv) > 1:
if sys.argv[1] in ['--service', 'service']:
run_mode = "windows_service"
elif sys.argv[1] in ['--standalone', 'standalone']:
run_mode = "standalone"
elif sys.argv[1] in ['--test', 'test']:
run_mode = "test"
logging.info(f"Running in '{run_mode}' mode")
if run_mode == "test":
# Test mode - just verify setup and exit
logging.info("=== SERVICE TEST MODE ===")
test_service_setup()
return
try:
# Start HTTP server
server_address = ('localhost', 8765)
# Try to bind to the port
try:
httpd_server = ThreadingHTTPServer(server_address, PrintServiceHandler)
except OSError as e:
if "Address already in use" in str(e):
logging.error(f"Port 8765 is already in use. Another service instance may be running.")
logging.error("Stop the existing service or use a different port.")
return
else:
raise
logging.info(f"Print service started on http://{server_address[0]}:{server_address[1]}")
logging.info("Available endpoints:")
logging.info(" GET /health - Health check")
logging.info(" GET /printers - List available printers")
logging.info(" GET /status - Service status")
logging.info(" POST /print_pdf - Print PDF file")
# Keep track of requests
httpd_server.request_count = 0
# Service main loop
logging.info("Service is ready and listening...")
if run_mode == "standalone":
logging.info("*** STANDALONE MODE - Press Ctrl+C to stop ***")
logging.info("Test the service at: http://localhost:8765/health")
while service_running:
try:
# Handle requests with timeout to check service_running periodically
httpd_server.timeout = 1.0
httpd_server.handle_request()
except KeyboardInterrupt:
logging.info("Service stopped by user (Ctrl+C)")
break
except Exception as e:
logging.error(f"Request handling error: {e}")
# Continue running unless it's a critical error
if not service_running:
break
except Exception as e:
logging.error(f"Critical service error: {e}")
import traceback
logging.error(f"Traceback: {traceback.format_exc()}")
finally:
# Cleanup
if httpd_server:
try:
httpd_server.server_close()
except:
pass
logging.info("=== Windows Print Service shutdown complete ===")
# Exit cleanly
sys.exit(0)
def test_service_setup():
"""Test service setup and configuration."""
logging.info("Testing service setup...")
# Test printer detection
try:
# Create a temporary handler instance to test printer detection
import tempfile
temp_handler = PrintServiceHandler()
temp_handler.temp_dir = tempfile.mkdtemp(prefix="test_service_")
printers = temp_handler.get_available_printers()
logging.info(f"Found {len(printers)} printers:")
for printer in printers[:5]: # Show first 5
logging.info(f" - {printer.get('name', 'Unknown')}")
# Cleanup temp directory
try:
import shutil
shutil.rmtree(temp_handler.temp_dir)
except:
pass
except Exception as e:
logging.warning(f"Printer detection test failed: {e}")
# Test port availability
try:
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('localhost', 8765))
logging.info("Port 8765 is available ✓")
except OSError as e:
logging.error(f"Port 8765 test failed: {e}")
logging.info("Service setup test completed")
if __name__ == "__main__":
main()

View File

@@ -1,35 +0,0 @@
# Windows Print Service - Complete Requirements
# All dependencies needed for the self-contained service
# Core Python libraries (usually built-in)
# These should be available in any Python 3.7+ installation
# For HTTP server
http.server
socketserver
urllib.request
urllib.parse
# For system operations
os
sys
subprocess
tempfile
shutil
pathlib
# For data handling
json
logging
threading
time
datetime
# For Windows-specific operations
# These are handled by subprocess calls to Windows commands
# Optional: PyInstaller for creating standalone executable
# PyInstaller==5.13.2
# Note: This service is designed to work with Python standard library only
# No external dependencies required for basic functionality

View File

@@ -1,259 +0,0 @@
"""
Windows Service Implementation - Alternative Approach
Uses Windows Task Scheduler as fallback if SC service fails
"""
import sys
import os
import subprocess
import time
import logging
from pathlib import Path
def create_scheduled_task_service():
"""Create Windows service using Task Scheduler as fallback."""
service_name = "QualityPrintService"
service_script = Path(__file__).parent / "print_service_complete.py"
python_exe = sys.executable
# Create XML for scheduled task
task_xml = f'''<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2025-09-26T12:00:00</Date>
<Author>Quality Print Service</Author>
<Description>Quality Print Service - Automatic Label Printing</Description>
</RegistrationInfo>
<Triggers>
<BootTrigger>
<Enabled>true</Enabled>
</BootTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-5-18</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<RestartOnFailure>
<Interval>PT5M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>"{python_exe}"</Command>
<Arguments>"{service_script}" --service</Arguments>
<WorkingDirectory>{service_script.parent}</WorkingDirectory>
</Exec>
</Actions>
</Task>'''
# Save task XML to file
task_xml_file = Path(__file__).parent / f"{service_name}_task.xml"
with open(task_xml_file, 'w', encoding='utf-16') as f:
f.write(task_xml)
return task_xml_file
def install_service_alternative():
"""Install service using multiple methods."""
print("🔧 Installing Windows Print Service with Multiple Methods...")
service_name = "QualityPrintService"
service_display_name = "Quality Print Service"
service_script = Path(__file__).parent / "print_service_complete.py"
python_exe = sys.executable
# Method 1: Try SC command with service wrapper
print("\n📋 Method 1: Windows SC Service")
try:
# Create service wrapper batch file
wrapper_bat = Path(__file__).parent / "service_wrapper.bat"
wrapper_content = f'''@echo off
REM Windows Print Service Wrapper - Error 1053 Fix
cd /d "{service_script.parent}"
REM Set error handling
setlocal enabledelayedexpansion
REM Log startup
echo %date% %time% - Service starting... >> service_startup.log
REM Check if Python exists
if not exist "{python_exe}" (
echo ERROR: Python not found at {python_exe} >> service_startup.log
exit /b 1
)
REM Check if service script exists
if not exist "{service_script}" (
echo ERROR: Service script not found at {service_script} >> service_startup.log
exit /b 1
)
REM Start the service with timeout monitoring
echo Starting service process... >> service_startup.log
"{python_exe}" "{service_script}" --service
REM Log exit
echo %date% %time% - Service exited with code %errorlevel% >> service_startup.log
'''
with open(wrapper_bat, 'w') as f:
f.write(wrapper_content)
# Remove existing service
subprocess.run(['sc', 'stop', service_name], capture_output=True)
subprocess.run(['sc', 'delete', service_name], capture_output=True)
# Create service
cmd = [
'sc', 'create', service_name,
f'binPath= "{wrapper_bat}"',
f'DisplayName= "{service_display_name}"',
'start= auto'
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print("✅ SC Service created successfully")
# Configure recovery
subprocess.run([
'sc', 'failure', service_name,
'reset= 86400',
'actions= restart/5000/restart/5000/restart/5000'
], capture_output=True)
# Try to start
start_result = subprocess.run(['sc', 'start', service_name], capture_output=True, text=True)
if start_result.returncode == 0:
print("✅ SC Service started successfully")
return True
else:
print(f"⚠️ SC Service created but failed to start: {start_result.stderr}")
else:
print(f"❌ SC Service creation failed: {result.stderr}")
except Exception as e:
print(f"❌ SC Service method failed: {e}")
# Method 2: Task Scheduler fallback
print("\n📋 Method 2: Task Scheduler Service")
try:
task_xml_file = create_scheduled_task_service()
# Remove existing task
subprocess.run(['schtasks', '/delete', '/tn', service_name, '/f'], capture_output=True)
# Create task
cmd = [
'schtasks', '/create', '/tn', service_name,
'/xml', str(task_xml_file)
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print("✅ Task Scheduler service created successfully")
# Start task
start_result = subprocess.run(['schtasks', '/run', '/tn', service_name], capture_output=True, text=True)
if start_result.returncode == 0:
print("✅ Task Scheduler service started successfully")
return True
else:
print(f"⚠️ Task created but failed to start: {start_result.stderr}")
else:
print(f"❌ Task Scheduler creation failed: {result.stderr}")
except Exception as e:
print(f"❌ Task Scheduler method failed: {e}")
# Method 3: Manual startup script
print("\n📋 Method 3: Startup Script")
try:
startup_script = Path(os.environ.get('APPDATA', '')) / 'Microsoft' / 'Windows' / 'Start Menu' / 'Programs' / 'Startup' / 'QualityPrintService.bat'
startup_script.parent.mkdir(parents=True, exist_ok=True)
startup_content = f'''@echo off
REM Quality Print Service - Startup Script
cd /d "{service_script.parent}"
start /min "Quality Print Service" "{python_exe}" "{service_script}" --service
'''
with open(startup_script, 'w') as f:
f.write(startup_content)
print(f"✅ Startup script created: {startup_script}")
print("🔄 Service will start automatically on next reboot")
# Start immediately
subprocess.run(['cmd', '/c', str(startup_script)], capture_output=True)
print("✅ Service started via startup script")
return True
except Exception as e:
print(f"❌ Startup script method failed: {e}")
print("\n❌ All installation methods failed")
return False
def test_service_connection(timeout=10):
"""Test if service is running by checking HTTP endpoint."""
import urllib.request
import json
for i in range(timeout):
try:
with urllib.request.urlopen('http://localhost:8765/health', timeout=2) as response:
data = json.loads(response.read().decode())
if data.get('status') == 'healthy':
return True
except:
pass
time.sleep(1)
return False
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == 'install':
success = install_service_alternative()
if success:
print("\n🧪 Testing service connection...")
if test_service_connection():
print("✅ Service is responding correctly!")
print("🌐 Test URL: http://localhost:8765/health")
else:
print("⚠️ Service installed but not responding")
print("📋 Check logs and try manual start")
else:
print("\n❌ Service installation failed")
print("📋 Try running as Administrator")
sys.exit(1)
else:
print("Usage: python service_installer.py install")

View File

@@ -1,175 +0,0 @@
#!/usr/bin/env python3
"""
Windows Service Wrapper - Handles Windows Service Communication
Fixes Error 1053 by properly communicating with Service Control Manager
"""
import sys
import os
import time
import logging
import subprocess
import threading
import signal
from pathlib import Path
# Simple service state management
class WindowsServiceManager:
def __init__(self):
self.service_process = None
self.should_stop = False
self.service_thread = None
def setup_logging(self):
"""Setup service logging."""
log_dir = os.path.join(os.path.expanduser("~"), "PrintService", "logs")
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, f"service_wrapper_{time.strftime('%Y%m%d')}.log")
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(log_file, encoding='utf-8'),
logging.StreamHandler(sys.stdout)
]
)
def signal_handler(self, signum, frame):
"""Handle shutdown signals."""
logging.info(f"Service wrapper received signal {signum}")
self.stop_service()
def start_service(self):
"""Start the actual print service."""
script_dir = Path(__file__).parent
service_script = script_dir / "print_service_complete.py"
if not service_script.exists():
logging.error(f"Service script not found: {service_script}")
return False
try:
# Get Python executable path
python_exe = sys.executable
if not python_exe:
python_exe = "python"
logging.info(f"Starting print service with: {python_exe} {service_script}")
# Start the service process
self.service_process = subprocess.Popen(
[python_exe, str(service_script), "--service"],
cwd=str(script_dir),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
universal_newlines=True
)
# Monitor service output
def monitor_output():
if self.service_process:
for line in iter(self.service_process.stdout.readline, ''):
if line:
logging.info(f"Service: {line.strip()}")
if self.should_stop:
break
self.service_thread = threading.Thread(target=monitor_output, daemon=True)
self.service_thread.start()
logging.info("Print service started successfully")
return True
except Exception as e:
logging.error(f"Failed to start service: {e}")
return False
def stop_service(self):
"""Stop the print service."""
logging.info("Stopping print service...")
self.should_stop = True
if self.service_process:
try:
# Try graceful shutdown first
self.service_process.terminate()
# Wait up to 10 seconds for graceful shutdown
for _ in range(10):
if self.service_process.poll() is not None:
break
time.sleep(1)
# Force kill if still running
if self.service_process.poll() is None:
logging.warning("Force killing service process")
self.service_process.kill()
self.service_process.wait()
logging.info("Print service stopped")
except Exception as e:
logging.error(f"Error stopping service: {e}")
def run_service(self):
"""Main service loop."""
logging.info("Windows Print Service Wrapper starting...")
# Setup signal handlers
signal.signal(signal.SIGTERM, self.signal_handler)
signal.signal(signal.SIGINT, self.signal_handler)
if hasattr(signal, 'SIGBREAK'):
signal.signal(signal.SIGBREAK, self.signal_handler)
# Start the actual service
if not self.start_service():
logging.error("Failed to start print service")
return 1
# Service main loop - keep running until stopped
try:
while not self.should_stop:
# Check if service process is still running
if self.service_process and self.service_process.poll() is not None:
logging.warning("Service process died, restarting...")
if not self.start_service():
logging.error("Failed to restart service")
break
time.sleep(5) # Check every 5 seconds
except KeyboardInterrupt:
logging.info("Service interrupted by user")
except Exception as e:
logging.error(f"Service loop error: {e}")
finally:
self.stop_service()
logging.info("Windows Print Service Wrapper stopped")
return 0
def main():
"""Main entry point."""
service_manager = WindowsServiceManager()
service_manager.setup_logging()
# Check command line arguments
if len(sys.argv) > 1:
if sys.argv[1] == "install":
logging.info("Service install requested - use install_service_complete.bat instead")
return 1
elif sys.argv[1] == "start":
logging.info("Service start requested")
elif sys.argv[1] == "stop":
logging.info("Service stop requested")
return 0
# Run the service
return service_manager.run_service()
if __name__ == "__main__":
sys.exit(main())

View File

@@ -1,57 +0,0 @@
@echo off
REM Windows Print Service - Troubleshooting and Testing Script
REM Use this to test the service before installing it as a Windows service
echo =========================================
echo Windows Print Service - Test Mode
echo =========================================
echo.
REM Set variables
set CURRENT_DIR=%~dp0
set SERVICE_NAME=QualityPrintService
set INSTALL_DIR=C:\QualityPrintService
set PYTHON_EXE=%INSTALL_DIR%\python_embedded\python.exe
set PYTHON_SCRIPT=%INSTALL_DIR%\print_service_complete.py
echo [INFO] Testing service in standalone mode...
echo [INFO] This helps diagnose issues before installing as Windows service
echo.
REM Check if files exist
if not exist "%PYTHON_EXE%" (
echo [ERROR] Python not found at: %PYTHON_EXE%
echo [INFO] Make sure the service is installed first using install_service_complete.bat
pause
exit /b 1
)
if not exist "%PYTHON_SCRIPT%" (
echo [ERROR] Service script not found at: %PYTHON_SCRIPT%
echo [INFO] Make sure the service is installed first using install_service_complete.bat
pause
exit /b 1
)
echo [INFO] Files found, starting service test...
echo [INFO] Python: %PYTHON_EXE%
echo [INFO] Script: %PYTHON_SCRIPT%
echo.
echo [INFO] Starting service in test mode...
echo [INFO] Press Ctrl+C to stop the service
echo [INFO] Service will run on http://localhost:8765
echo.
REM Change to service directory
cd /d "%INSTALL_DIR%"
REM Start service in standalone mode for testing
"%PYTHON_EXE%" "%PYTHON_SCRIPT%" --standalone
echo.
echo [INFO] Service test completed.
echo [INFO] If the service ran successfully above, you can now:
echo [INFO] 1. Test it: http://localhost:8765/health
echo [INFO] 2. Start Windows service: net start %SERVICE_NAME%
echo.
pause

View File

@@ -1,89 +0,0 @@
@echo off
echo ========================================
echo Quality Print Service - Uninstaller
echo ========================================
echo.
REM Check for administrator privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
echo ERROR: This uninstaller requires Administrator privileges.
echo Please right-click this file and select "Run as administrator"
echo.
pause
exit /b 1
)
echo Administrator privileges confirmed ✓
echo.
set SERVICE_NAME=QualityPrintService
set INSTALL_DIR=C:\QualityPrintService
set LOG_DIR=%USERPROFILE%\PrintService
echo Removing Quality Print Service...
echo.
REM Stop and remove Windows service
echo [1/4] Stopping Windows service...
sc stop "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo Service stopped ✓
timeout /t 3 >nul
) else (
echo Service was not running
)
echo [2/4] Removing Windows service...
sc delete "%SERVICE_NAME%" >nul 2>&1
if %errorLevel% equ 0 (
echo Service removed ✓
) else (
echo Service was not installed or already removed
)
REM Remove scheduled task fallback
echo [3/4] Removing scheduled task (if exists)...
schtasks /delete /tn "%SERVICE_NAME%" /f >nul 2>&1
if %errorLevel% equ 0 (
echo Scheduled task removed ✓
) else (
echo No scheduled task found
)
REM Remove installation files
echo [4/4] Removing installation files...
if exist "%INSTALL_DIR%" (
echo Removing installation directory: %INSTALL_DIR%
rmdir /s /q "%INSTALL_DIR%" >nul 2>&1
if %errorLevel% equ 0 (
echo Installation directory removed ✓
) else (
echo WARNING: Could not remove all installation files
echo You may need to manually delete: %INSTALL_DIR%
)
) else (
echo Installation directory not found
)
echo.
echo ========================================
echo Uninstallation Complete
echo ========================================
echo.
echo What was removed:
echo ✓ Windows service: %SERVICE_NAME%
echo ✓ Installation files: %INSTALL_DIR%
echo ✓ Scheduled task (if existed)
echo.
echo What was kept (optional cleanup):
echo - Log files: %LOG_DIR%
echo - Chrome extension (manual removal required)
echo.
echo To completely remove logs:
echo rmdir /s /q "%LOG_DIR%"
echo.
echo To remove Chrome extension:
echo Go to chrome://extensions/ and remove "Quality Print Service"
echo.
pause