Is it possible to get a list of printer names in Windows?
Question: I'm trying to create an automatic printer installer for Windows.

If I wanted to pull a list of printers, how would I go about that in Python? I
know there's a way to get a list using a VB script on the command line, but
that gives me additional information I don't need, plus there's no real good
way to import the data into Python (that I know of)

The reasons for doing this is to get the values and put them in a list, and
then have them check against another list. Anything in the one list will be
removed. That ensures that the program won't install duplicate printers.


Answer: You can use [pywin32](http://sourceforge.net/projects/pywin32/files/)'s
`win32print.EnumPrinters()` (more convenient), or invoke the `EnumPrinters()`
API via the `ctypes` module (low dependency).

Here is a fully working `ctypes` version w/o error checking.

    
    
    # Use EnumPrintersW to list local printers with their names and descriptions.
    # Tested with CPython 2.7.10 and IronPython 2.7.5.
    
    import ctypes
    from ctypes.wintypes import BYTE, DWORD, LPCWSTR
    
    winspool = ctypes.WinDLL('winspool.drv')  # for EnumPrintersW
    msvcrt = ctypes.cdll.msvcrt  # for malloc, free
    
    # Parameters: modify as you need. See MSDN for detail.
    PRINTER_ENUM_LOCAL = 2
    Name = None  # ignored for PRINTER_ENUM_LOCAL
    Level = 1  # or 2, 4, 5
    
    class PRINTER_INFO_1(ctypes.Structure):
        _fields_ = [
            ("Flags", DWORD),
            ("pDescription", LPCWSTR),
            ("pName", LPCWSTR),
            ("pComment", LPCWSTR),
        ]
    
    # Invoke once with a NULL pointer to get buffer size.
    info = ctypes.POINTER(BYTE)()
    pcbNeeded = DWORD(0)
    pcReturned = DWORD(0)  # the number of PRINTER_INFO_1 structures retrieved
    winspool.EnumPrintersW(PRINTER_ENUM_LOCAL, Name, Level, ctypes.byref(info), 0,
            ctypes.byref(pcbNeeded), ctypes.byref(pcReturned))
    
    bufsize = pcbNeeded.value
    buffer = msvcrt.malloc(bufsize)
    winspool.EnumPrintersW(PRINTER_ENUM_LOCAL, Name, Level, buffer, bufsize,
            ctypes.byref(pcbNeeded), ctypes.byref(pcReturned))
    info = ctypes.cast(buffer, ctypes.POINTER(PRINTER_INFO_1))
    for i in range(pcReturned.value):
        print info[i].pName, '=>', info[i].pDescription
    msvcrt.free(buffer)
    

