Skip to content

Instantly share code, notes, and snippets.

@Thong-Tran
Last active May 27, 2022 11:09
Show Gist options
  • Save Thong-Tran/04eed7ce2d31e7e08f1b8623e5c7f102 to your computer and use it in GitHub Desktop.
Save Thong-Tran/04eed7ce2d31e7e08f1b8623e5c7f102 to your computer and use it in GitHub Desktop.
Modify document by vitual printer

Modify document by vitual printer

Modify document when printing in Windows by create virtual printer

import subprocess
import socket
import select
# pywin32 extension
import win32print
import pywintypes
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 8888 # Port to listen on (non-privileged ports are > 1023)
PRINTER_NAME = 'Virtual Printer'
def create_port_printer(host: str, port: int):
'''Register tcp port for printer, using `cscript prnport.vbs`'''
create_port_cmd = 'cscript c:\\Windows\\System32\\Printing_Admin_Scripts\\en-US\\prnport.vbs -a -r {ip}:{port} -h {ip} -o raw -n {port}'
subprocess.check_output(create_port_cmd.format(ip=host, port=port), shell=True)
def create_printer(printer_name: str, host: str, port: int, driver_name='Microsoft Software Printer Driver') -> object:
'''Create a new printer, if exist return it'''
try:
return win32print.OpenPrinter(printer_name)
except pywintypes.error as e:
pass
printer_info = {
'pPrinterName': printer_name,
'pDevMode': pywintypes.DEVMODEType(),
'pDriverName': driver_name,
'pPortName': f'{host}:{port}',
'pPrintProcessor': 'WinPrint',
'Attributes': 0,
'AveragePPM': 0,
'cJobs': 0,
'DefaultPriority': 0,
'Priority': 0,
'StartTime': 0,
'Status': 0,
'UntilTime': 0,
'pComment': '',
'pLocation': '',
'pDatatype': None,
'pParameters': None,
'pSecurityDescriptor': None,
'pSepFile': None,
'pServerName': None,
'pShareName': None
}
h_printer = win32print.AddPrinter(None, 2, printer_info)
return h_printer
def send_to_printer(raw_data: bytes, printer='Microsoft Print to PDF', out_file='out_file'):
'''Send XPS data to printer'''
hPrinter = win32print.OpenPrinter(printer)
try:
hJob = win32print.StartDocPrinter(hPrinter, 1, (out_file, None, "RAW"))
try:
win32print.StartPagePrinter(hPrinter)
win32print.WritePrinter(hPrinter, raw_data)
win32print.EndPagePrinter(hPrinter)
finally:
win32print.EndDocPrinter(hPrinter)
finally:
win32print.ClosePrinter(hPrinter)
def run_server(host: str, port: int):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.bind((host, port))
server_socket.listen()
print("Listening ...")
try:
while True:
readable, _, _ = select.select([server_socket], [], [], 1)
for s in readable:
raw = b''
client_socket, address = s.accept()
print('Connected by', address)
while True:
data = client_socket.recv(1024)
if data:
raw += data
else:
client_socket.close()
break
# Modify data
xps_bytes = raw
# Reprint it
send_to_printer(xps_bytes)
except KeyboardInterrupt:
print('Closing ...')
if __name__ == "__main__":
create_port_printer(HOST, PORT)
create_printer(PRINTER_NAME, HOST, PORT)
run_server(HOST, PORT)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment