Seite 1 von 1

win32print.OpenPrinter mit PRINTER_DEFAULTS

Verfasst: Mittwoch 10. Februar 2010, 14:54
von droptix
Ich möchte mittels Python und win32print den Druckeranschluss eines Druckers umstellen. Dazu muss ich als erstes den Drucker "öffnen", also ein Handle erzeugen:

Code: Alles auswählen

h = win32print.OpenPrinter("Druckername")
Das Problem dabei ist, dass der Drucker nur zum Lesen geöffnet wird, mir fehlen die Rechte etwas darin umzustellen. Ein Beispiel:

Code: Alles auswählen

printerName = win32print.GetDefaultPrinter()
h = win32print.OpenPrinter(printerName)
settings = win32print.GetPrinter(h, 2) # 2 ist das Data Level
settings["pPortName"] = "NUL"
win32print.SetPrinter(h, 2, settings, 0)
Ich erhalte als Fehler:

Code: Alles auswählen

error: (5, 'SetPrinter', 'Zugriff verweigert')
Ich habe gelesen, dass bei OpenPrinter bereits darauf geachtet werden muss, dass man die richtigen Zugriffsrechte erlangt. Dies geschiet durch die Angabe von PRINTER_DEFAULTS (Standard: None). Der dritte Wert in PRINTER_DEFAULTS ist DesiredAccess, den ich anscheinend auf PRINTER_ACCESS_ADMINISTER umstellen muss.

Ich weiß nur nicht wie? Für VB-Script & Co. findet man einige Beispiele, aber ich kann es mir nicht zusammen reimen.

Kann mir das jemand nach Python übersetzen?

Verfasst: Mittwoch 10. Februar 2010, 21:17
von droptix
Ich benötige eigentlich nur ein leeres PRINTER_DEFAULTS Objekt (dict). Also dasselbe was passiert wenn man bei OpenPrinter kein zweites Argument (Default) bzw. None übergeben wird.

Kann mir jmd. helfen das zu "erstellen"?

Verfasst: Donnerstag 11. Februar 2010, 00:34
von querdenker
Suchbegriffe : python win32print example

Augenscheinlich bestes Ergebnis

gelöst

Verfasst: Donnerstag 11. Februar 2010, 08:45
von droptix
Jippieh! Danke, ich hab mich gestern wirklich tot gegoogelt... aber wie das so ist, dann fährt man sich irgendwann fest, DANKE!

Verfasst: Donnerstag 11. Februar 2010, 20:11
von querdenker
Gern geschehen!

nächste Herausforderung

Verfasst: Samstag 13. Februar 2010, 02:32
von droptix
Bin nun ein ganzes Stück weiter gekommen und scheitere nun daran, dass ich über win32print nicht auf FindFirstPrinterChangeNotification zugreifen kann. Die MSDN Library listet unter Printing and Print Spooler Functions viel mehr Funktionen auf als mir win32print zur Verfügung stellt.

Woran liegt das? Ich dachte pywin32 stellt direkten Kontakt zur Win32 API bereit.

Jedenfalls muss ich dafür nun einen anderen Weg gehen. Ich habe dabei an `ctypes` gedacht. Ich scheitere schon beim Öffnen des Druckers mit erweiterten Rechten. Mit Standardrechten geht's, aber die reichen eben nicht. Der Fehler muss in meiner PRINTER_DEFAULTS Struktur liegen. Wer weiß Rat?

Code: Alles auswählen

import ctypes

DLL = ctypes.windll.LoadLibrary("winspool.drv")

PRINTER_ALL_ACCESS = 0xF000C

class PRINTER_DEFAULTS(ctypes.Structure):
    _fields_ = [
        ("pDatatype", ctypes.c_void_p),
        ("pDevMode", ctypes.c_void_p),
        ("DesiredAccess", ctypes.c_void_p)            
    ]

def PrinterDefaults():
    # PRINTER_DEFAULTS structure for PRINTER_ALL_ACCESS
    return PRINTER_DEFAULTS(None, None, PRINTER_ALL_ACCESS)

def OpenPrinter(pPrinterName, allAccess=False):
    # opens the printer specified by pPrinterName and returns a handle
    handle = ctypes.c_int(32)
    phPrinter = ctypes.byref(handle)
    if allAccess:
        pDefault = PrinterDefaults()
    else:
        pDefault = None
    DLL.OpenPrinterA(pPrinterName, phPrinter, pDefault)
    return handle

OpenPrinter("Druckername", True)

"""Fehler:
DLL.OpenPrinterA(pPrinterName, phPrinter, pDefault)
ValueError: Procedure probably called with too many arguments (8 bytes in excess)
"""