406 lines
14 KiB
Python
406 lines
14 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script to create a completely self-contained Windows Print Service package
|
|
with embedded Python distribution - Zero external dependencies required!
|
|
"""
|
|
|
|
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",
|
|
"install_service_complete.bat",
|
|
"uninstall_service_complete.bat",
|
|
"INSTALLATION_COMPLETE.md",
|
|
"PACKAGE_SUMMARY.md",
|
|
"README_COMPLETE.md"
|
|
]
|
|
|
|
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📦 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")
|
|
|
|
return True
|
|
|
|
if __name__ == "__main__":
|
|
print("🚀 Creating Complete Zero-Dependencies Package...")
|
|
print("=" * 60)
|
|
|
|
if create_complete_package():
|
|
print("\n✅ SUCCESS: Complete package created!")
|
|
print("\n📋 Next steps:")
|
|
print("1. Test the package on a clean Windows system")
|
|
print("2. Verify zero external dependencies")
|
|
print("3. Update Flask app to serve this package")
|
|
else:
|
|
print("\n❌ FAILED: Package creation failed")
|
|
sys.exit(1) |