已收到打印作业 Python
Received Print Job Python
在假脱机期间最初在本地计算机上请求打印作业时,我已成功触发回调。然而,有没有 win32print
或类似的东西可以让我处理将打印作业传输到打印服务器或 USB 打印机的事件?
################################################################################
# Imports ######################################################################
################################################################################
from os.path import *
from printer import *
from watcher import *
from statvar import *
################################################################################
# Event Callback ###############################################################
################################################################################
def callback(code, event):
num = splitext(event)[0]
ext = splitext(event)[1]
if code == 1 and ext == '.SPL':
main(num.lstrip('0'))
################################################################################
# wx Event Handler #############################################################
################################################################################
def handling(*args):
wx.CallAfter(callback, *args)
################################################################################
# Create Listener ##############################################################
################################################################################
# listens to the spool directory for files
watch = Watcher(SPOOL_DIRECTORY, handling)
# set the appropriate flags for a listener
watch.flags = FILE_NOTIFY_CHANGE_FILE_NAME
################################################################################
# Start Listener ###############################################################
################################################################################
watch.start()
################################################################################
# Start wx App #################################################################
################################################################################
app = wx.App()
wx.Frame(None)
app.MainLoop()
################################################################################
################################################################################
################################################################################
这是一个在我的电脑上可行的想法 (Windows 8)。它不是完全成熟的代码,但它可能会让你继续。你需要使用函数 FindFirstPrinterChangeNotification
and FindNextPrinterChangeNotification
These are contained within winspool.drv
on the client side (irritatingly you can find them documented as being in spoolSS.dll
but this is server side - this diagram 可以澄清)。
可从 MSDN here 获得可以监听的事件列表(重要的是,它们的标志设置)。最初我以为你想要 PRINTER_CHANGE_ADD_JOB
(0x00000100
),但我认为你实际上可能想要 PRINTER_CHANGE_WRITE_JOB
(0x00000800
)。这不会在作业开始假脱机时立即触发,但不幸的是,在您将一个文档发送到网络打印机的示例中,它似乎确实被触发了多次。
遗憾的是,这些 API 未在 win32print
库中公开。我认为,因此您必须深入研究 ctypes
。在这里我没有注册回调,而是监听通知,当触发时我调用该函数并在无限循环中再次开始监听。该过程在收听时停滞。如果您需要传统的回调功能,您可以 运行 这个脚本在它自己的线程中,或者这个答案可能不适合您的需要。
注意 - 这只是监听正在请求的打印作业,然后调用一个函数。如果你想提取有关被触发的作业的信息,代码将变得可怕。进一步注意 - 它会触发开始并随后取消的打印作业,但我想这很好。
from ctypes import *
from ctypes.wintypes import HANDLE, LPSTR
def add_job_callback():
print('A job has just been sent to the printer this script is monitoring')
spl = windll.LoadLibrary('winspool.drv')
printer_name = 'KONICA MINOLTA PS Color Laser Class Driver'
# Put the name of your printer here - can be networked or any installed on your computer. Alternatively, set it to None to use the local printer server
#printer_name = None
hPrinter = HANDLE()
if printer_name:
spl.OpenPrinterA(c_char_p(printer_name), byref(hPrinter),None)
else:
spl.OpenPrinterA(None, byref(hPrinter),None)
print(hPrinter)
hjob = spl.FindFirstPrinterChangeNotification(hPrinter,0x00000100,0, None)
# 0x00000100 is a flags setting to set watch for only PRINTER_CHANGE_ADD_JOB
while True:
windll.kernel32.WaitForSingleObject(hjob,-1)
#When this function returns, the change that you're monitoring for has been observed, trigger the function
add_job_callback()
spl.FindNextPrinterChangeNotification(hjob, None, None, None)
请注意 Python 2.7 和 Python 3 之间存在一些细微差异 - 例如从字符串中初始化 c_char_p
ctype
。我在这里展示了我所能提供的最简单的版本——它适用于 2.7。
后记
我完成了所有繁重的工作,然后发现 this answer,这是一个重复的东西。它有更好的代码来处理 unicode 打印机名称等,但只查看默认的本地打印服务器。
在假脱机期间最初在本地计算机上请求打印作业时,我已成功触发回调。然而,有没有 win32print
或类似的东西可以让我处理将打印作业传输到打印服务器或 USB 打印机的事件?
################################################################################
# Imports ######################################################################
################################################################################
from os.path import *
from printer import *
from watcher import *
from statvar import *
################################################################################
# Event Callback ###############################################################
################################################################################
def callback(code, event):
num = splitext(event)[0]
ext = splitext(event)[1]
if code == 1 and ext == '.SPL':
main(num.lstrip('0'))
################################################################################
# wx Event Handler #############################################################
################################################################################
def handling(*args):
wx.CallAfter(callback, *args)
################################################################################
# Create Listener ##############################################################
################################################################################
# listens to the spool directory for files
watch = Watcher(SPOOL_DIRECTORY, handling)
# set the appropriate flags for a listener
watch.flags = FILE_NOTIFY_CHANGE_FILE_NAME
################################################################################
# Start Listener ###############################################################
################################################################################
watch.start()
################################################################################
# Start wx App #################################################################
################################################################################
app = wx.App()
wx.Frame(None)
app.MainLoop()
################################################################################
################################################################################
################################################################################
这是一个在我的电脑上可行的想法 (Windows 8)。它不是完全成熟的代码,但它可能会让你继续。你需要使用函数 FindFirstPrinterChangeNotification
and FindNextPrinterChangeNotification
These are contained within winspool.drv
on the client side (irritatingly you can find them documented as being in spoolSS.dll
but this is server side - this diagram 可以澄清)。
可从 MSDN here 获得可以监听的事件列表(重要的是,它们的标志设置)。最初我以为你想要 PRINTER_CHANGE_ADD_JOB
(0x00000100
),但我认为你实际上可能想要 PRINTER_CHANGE_WRITE_JOB
(0x00000800
)。这不会在作业开始假脱机时立即触发,但不幸的是,在您将一个文档发送到网络打印机的示例中,它似乎确实被触发了多次。
遗憾的是,这些 API 未在 win32print
库中公开。我认为,因此您必须深入研究 ctypes
。在这里我没有注册回调,而是监听通知,当触发时我调用该函数并在无限循环中再次开始监听。该过程在收听时停滞。如果您需要传统的回调功能,您可以 运行 这个脚本在它自己的线程中,或者这个答案可能不适合您的需要。
注意 - 这只是监听正在请求的打印作业,然后调用一个函数。如果你想提取有关被触发的作业的信息,代码将变得可怕。进一步注意 - 它会触发开始并随后取消的打印作业,但我想这很好。
from ctypes import *
from ctypes.wintypes import HANDLE, LPSTR
def add_job_callback():
print('A job has just been sent to the printer this script is monitoring')
spl = windll.LoadLibrary('winspool.drv')
printer_name = 'KONICA MINOLTA PS Color Laser Class Driver'
# Put the name of your printer here - can be networked or any installed on your computer. Alternatively, set it to None to use the local printer server
#printer_name = None
hPrinter = HANDLE()
if printer_name:
spl.OpenPrinterA(c_char_p(printer_name), byref(hPrinter),None)
else:
spl.OpenPrinterA(None, byref(hPrinter),None)
print(hPrinter)
hjob = spl.FindFirstPrinterChangeNotification(hPrinter,0x00000100,0, None)
# 0x00000100 is a flags setting to set watch for only PRINTER_CHANGE_ADD_JOB
while True:
windll.kernel32.WaitForSingleObject(hjob,-1)
#When this function returns, the change that you're monitoring for has been observed, trigger the function
add_job_callback()
spl.FindNextPrinterChangeNotification(hjob, None, None, None)
请注意 Python 2.7 和 Python 3 之间存在一些细微差异 - 例如从字符串中初始化 c_char_p
ctype
。我在这里展示了我所能提供的最简单的版本——它适用于 2.7。
后记
我完成了所有繁重的工作,然后发现 this answer,这是一个重复的东西。它有更好的代码来处理 unicode 打印机名称等,但只查看默认的本地打印服务器。