Siemens NX(UG)Python 开发 – 枚举打印机

最近更新于 2025-11-02 20:18

前言

2025/11/2
我现在计划的需求是实现一键批量打印图纸。选择一个文件夹后,依次打开每个 prt 文件,检查是否有图纸页,有图纸页就遍历图纸页(可能多张图纸),根据图纸的尺寸自动选择图幅(可以提前设定各种图幅用多大的纸打印)。一键完成打印,而不是一个一个的去手动操作。
现在还在摸索 NXOpen,只是目前没发现 NXOpen 有提供枚举打印机的接口,就考虑调用 Windows API 来获取打印机列表了。在批量打印的时候要选择打印机,因此需要先枚举出打印机有哪些,用户才可以选择使用哪个打印机。

环境

  • Windows 11 25H2
  • NX 2506
  • 内置 Python 3.12.8

枚举打印机

import NXOpen

import ctypes
from ctypes import wintypes

# 枚举打印机所需的常量
PRINTER_ENUM_LOCAL = 2 # 本地打印机(含虚拟打印机)
PRINTER_ENUM_CONNECTIONS = 4 # 网络打印机

# 打印机属性标志
PRINTER_ATTRIBUTE_DEFAULT = 0x00000004
PRINTER_ATTRIBUTE_LOCAL = 0x00000002
PRINTER_ATTRIBUTE_NETWORK = 0x00000001
PRINTER_ATTRIBUTE_FAX = 0x00000200
PRINTER_ATTRIBUTE_SHARED = 0x00000008
PRINTER_ATTRIBUTE_HIDDEN = 0x00000020

class PRINTER_INFO_4(ctypes.Structure):
    """
    对应 Windows API 的 PRINTER_INFO_4 结构体,用于存储打印机信息
    字段:
        pPrinterName : 打印机名称(LPWSTR)
        pServerName  : 打印机所在服务器名称(网络打印机才有,本地打印机为 None)
        Attributes   : 打印机属性(DWORD),例如本地或远程等标记
    """
    _fields_ = [
        ("pPrinterName", wintypes.LPWSTR),
        ("pServerName", wintypes.LPWSTR),
        ("Attributes", wintypes.DWORD),
    ]

def enumPrinters() -> list:
    # 加载 Windows 的打印机库文件
    winspool = ctypes.WinDLL('winspool.drv')

    level = 4 # PRINTER_INFO_4 结构体的级别
    flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS # 枚举本地和网络打印机

    # 获取所需的缓冲区大小
    bufsize = wintypes.DWORD(0) # 缓冲区大小(字节)
    returned = wintypes.DWORD(0) # 实际返回的打印机数量
    winspool.EnumPrintersW(flags, None, level, None, 0, ctypes.byref(bufsize), ctypes.byref(returned))

    # 分配缓冲区
    buf = (ctypes.c_byte * bufsize.value)()

    # 获取打印机信息
    winspool.EnumPrintersW(flags, None, level, ctypes.byref(buf), bufsize, ctypes.byref(bufsize), ctypes.byref(returned))

    # 解析缓冲区中的打印机信息
    printers = []
    count = returned.value # 打印机数量
    pinfo = ctypes.cast(buf, ctypes.POINTER(PRINTER_INFO_4)) # 指向 PRINTER_INFO_4 结构体的指针
    for i in range(count):
        printers.append((pinfo[i].pPrinterName, pinfo[i].pServerName, pinfo[i].Attributes))

    return printers

def getPrinterAttributesText(attr: int) -> str:
    """获取打印机属性文本

    Args:
        attr (int): 打印机属性标志

    Returns:
        str: 打印机属性文本
    """
    types = []
    if attr & PRINTER_ATTRIBUTE_DEFAULT:
        types.append('默认')
    if attr & PRINTER_ATTRIBUTE_LOCAL:
        types.append('本地')
    if attr & PRINTER_ATTRIBUTE_NETWORK:
        types.append('网络')
    if attr & PRINTER_ATTRIBUTE_FAX:
        types.append('传真')
    if attr & PRINTER_ATTRIBUTE_SHARED:
        types.append('共享')
    if attr & PRINTER_ATTRIBUTE_HIDDEN:
        types.append('隐藏')
    if not types:
        types.append('未知')
    return ', '.join(types)

def nxLog(msg: str):
    lw = NXOpen.Session.GetSession().ListingWindow
    if not lw.IsOpen:
        lw.Open()
    lw.WriteLine(msg)

def main():
    printers = enumPrinters()
    for printer in printers:
        attrText = getPrinterAttributesText(printer[2])
        nxLog(f'打印机名称: {printer[0]}, 网络打印机服务器名称: {printer[1]}, 打印机属性: {attrText}')

if __name__ == '__main__':
    main()

Microsoft 和 Acrobat 的 PDF 生成器属性都是传真,Hexagon PC-DMIS 的 PDF 生成器属性倒是本地打印机,最下面两个是局域网连接的真实打印机,属性是传真和共享
file

Siemens NX(UG)Python 开发 – 枚举打印机
Scroll to top
打开目录