win32print.OpenPrinter mit PRINTER_DEFAULTS

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

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?
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

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"?
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Suchbegriffe : python win32print example

Augenscheinlich bestes Ergebnis
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Jippieh! Danke, ich hab mich gestern wirklich tot gegoogelt... aber wie das so ist, dann fährt man sich irgendwann fest, DANKE!
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Gern geschehen!
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

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)
"""
Antworten