1.打印

几个重要的函数接口
获取打印机属性部分:win32print.DeviceCapabilities
设置打印机部分 handle = win32print.OpenPrinter(device_name, printdefaults),其中printdefualts,表示权限,可以如下设置
printdefaults = {“DesiredAccess”: win32print.PRINTER_ALL_ACCESS}
printaccess = {“DesiredAccess”: win32print.PRINTER_ACCESS_USE}几个重要的函数接口
获取打印机属性部分:win32print.DeviceCapabilities
设置打印机部分 handle = win32print.OpenPrinter(device_name, printdefaults),其中printdefualts,表示权限,可以如下设置
printdefaults = {“DesiredAccess”: win32print.PRINTER_ALL_ACCESS}
printaccess = {“DesiredAccess”: win32print.PRINTER_ACCESS_USE}
调用 win32print.SetPrinter(handle, 2, properties, 0)来设置对应的打印机。这里就算出现异常,也可能设置成功的。
win32print.SetDefaultPrinter(device_name), 将打印机设置为默认打印机
win32api.ShellExecute(0, “print”, file_name, None, “.”, 0),最后调用函数打印文件file_name。
 

import win32print
import win32api
import win32con
import time


def pdf_print_device(file_names, device_name):
    printaccess = {"DesiredAccess": win32print.PRINTER_ACCESS_USE}
    try:
        handle = win32print.OpenPrinter(device_name, printaccess)
        win32print.ClosePrinter(handle)
        time.sleep(2)
        handle = win32print.OpenPrinter(device_name, printaccess)
        properties = win32print.GetPrinter(handle, 2)
        devmode = properties['pDevMode']
        devmode.PaperSize = 0  # 
        devmode.PaperLength = 3150  # .
        devmode.PaperWidth = 2500
        devmode.Duplex = win32con.DMDUP_SIMPLEX  # 单面
        devmode.Orientation = win32con.DMORIENT_LANDSCAPE  # 横向打印
        properties['pDevMode'] = devmode
        for temp_loop in range(2):
            try:
                win32print.SetPrinter(handle, 2, properties, 0)
            except Exception as ff:
                print(f'setprinters:{ff}')
            win32print.SetDefaultPrinter(device_name)

        for file_name in file_names:
            print(f'{device_name}打印文件{file_name}')
            win32api.ShellExecute(0, "print", file_name, None, ".", 0)
            time.sleep(2)
        win32print.ClosePrinter(handle)

    except Exception as first:
        print(f'first:{first}')


pdf_print_device(['pdf绝对路径'], '打印机名')

来自https://blog.csdn.net/sdfdsdfdf/article/details/106406291

这段代码使用了win32printwin32api模块,主要实现了通过指定打印机打印PDF文件的功能。以下是代码的主要内容以及涉及的知识点:

  1. win32print 模块:

    • OpenPrinter: 打开打印机对象,获取对打印机的访问权限。
    • GetPrinter: 获取打印机的属性,包括设备模式(devmode)等信息。
    • SetPrinter: 设置打印机的属性,例如设备模式。
    • SetDefaultPrinter: 将指定的打印机设置为系统的默认打印机。
    • ClosePrinter: 关闭打印机对象。
  2. win32api 模块:

    • ShellExecute: 启动与指定文件相关联的程序,这里用于通过关联的程序(通常是默认的PDF查看器)打印PDF文件。
  3. 设备模式 (devmode):

    • pDevMode: 打印机的设备模式,其中包含有关打印机的详细设置,如纸张大小、双面打印、打印方向等。
    • 在代码中,通过设置 devmode.PaperSizedevmode.PaperLengthdevmode.PaperWidthdevmode.Duplexdevmode.Orientation 等属性,控制打印机的一些设置。
  4. 定时等待:

    • time.sleep: 通过 time.sleep(2) 实现延迟,用于确保操作能够正确执行。在打印和设置打印机时,可能需要等待一段时间,以确保前一个操作已经完成。
  5. 异常处理:

    • 使用 try 和 except 处理异常。在实际应用中,处理异常是一个良好的编程实践,以防止程序崩溃并提供更好的用户体验。
  6. ShellExecute 的 "print" 操作:

    • 使用 win32api.ShellExecute 执行打印操作。这里通过 "print" 参数告诉系统打开关联的打印程序并打印指定的PDF文件。

总的来说,这段代码实现了通过指定打印机打印PDF文件的功能,并通过 win32print 和 win32api 模块实现了与打印机相关的操作。涉及的知识点包括打印机操作、设备模式设置、定时等待、异常处理以及调用外部程序打印文件。

 

   

win32print模块中,PRINTER_ALL_ACCESS是一个权限标志,它表示对打印机的所有访问权限¹²。这意味着你可以使用这个权限来读取和修改打印机的设置¹²。

除了PRINTER_ALL_ACCESSwin32print模块还提供了其他的权限标志,例如:

  • PRINTER_ACCESS_USE:这个权限允许你使用打印机,但不允许你修改打印机的设置¹。

这些权限标志可以用于OpenPrinter函数的DesiredAccess参数,来控制你对打印机的访问权限¹²。例如:

import win32print

# 获取打印机名称
printer_name = "你的打印机名称"  # 替换为你的打印机名称

# 打开打印机,使用所有访问权限
handle = win32print.OpenPrinter(printer_name, {"DesiredAccess": win32print.PRINTER_ALL_ACCESS})

# ...你可以在这里读取和修改打印机的设置...

# 关闭打印机
win32print.ClosePrinter(handle)

在这个示例中,我们使用PRINTER_ALL_ACCESS权限打开了打印机,这意味着我们可以读取和修改打印机的设置¹²。

报错

pywintypes.error: (5, 'SetPrinter', '拒绝访问。')

使用PRINTER_ALL_ACCESS

2.获取打印日志事件

在Windows中,您可以使用eventvwr.msc来查看所有打印机的日志。以下是具体步骤:

  1. 打开事件查看器:按下键盘上的Win键和R键,这将会打开运行对话框。在运行对话框中输入eventvwr.msc,然后按下Enter键。

  2. 查看打印服务日志:在事件查看器的左侧导航栏,展开「应用程序和服务日志」文件夹-「Microsoft」文件夹-「Windows」文件夹-「PrintService」文件夹¹。

  3. 启用日志记录:在「PrintService」窗格下,右键单击「Operational」条目,然后选择「属性」,启用日志记录¹。

  4. 查询打印日志:展开「Windows日志」文件夹-「系统」。在这里,您可以查看所有的打印机日志。

 

import subprocess

# 你的PowerShell命令
cmd = 'Get-WinEvent -FilterHashtable @{LogName="Microsoft-Windows-PrintService/Operational"; ID=307}'

# 使用subprocess来运行命令
process = subprocess.Popen(["powershell", cmd], stdout=subprocess.PIPE)

# 获取命令的执行结果(任务计划程序执行显示不全,待解决)
output = process.communicate()[0]

# 使用GBK编码来解码输出
print(output.decode('gbk'))

该代码将启动一个新的PowerShell进程,执行你的命令,然后获取命令的输出。请注意这个方式会捕获PowerShell命令的标准输出,如果PowerShell命令产生了错误,可能你需要处理该错误。

考虑到Windows事件日志可能需要管理员权限才能访问,你的Python程序可能需要以管理员权限运行才能正确获取日志条目。

此方法本质上还是在执行PowerShell命令,如果你的系统当前没有事件ID为307的事件记录,那么这个方法也同样无法获取到这样的事件。此时你可能需要检查系统的配置,确认哪些事件应该已经被记录但没有出现在日志中。