最近更新于 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 生成器属性倒是本地打印机,最下面两个是局域网连接的真实打印机,属性是传真和共享

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