Announcement

Collapse
No announcement yet.

PRINTER_INFO_2 unter NT

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • PRINTER_INFO_2 unter NT

    Hallo Herr Kosch und alle anderen,

    brauche dringend eine Lösung zu folgendem Problem:

    Ich versuche die DevMode-Struktur eines Druckers auf einem NT-Rechner (4.0, SP 5) zu ändern. (Änderung von Papierformat, Schacht und Ausrichtung) Ich benutze dazu (in einem Delphi 4-Prokekt) die Funktionen "OpenPrinter", "GetPrinter" und "SetPrinter" der WINSPOOL-Library. Als Parameter für "OpenPrinter" übergebe ich eine "PrinterDefaults"-Struktur, deren Wert für "DesiredAccess" auf "PRINTER_ALL_ACCESS" steht. In den Funktionen "GetPrinter" und "SetPrinter" ermittele bzw. ändere ich den DevMode-Teil der PRINTER_INFO_2 - Struktur. So weit, so gut !

    Alles funktioniert ohne die geringsten Probleme auf einem Windows 95 und auf einem Windows 98 - Rechner. Auf einem NT-Rechner muß der aktive Benutzer grundsätzlich erstens Vollzugriff auf den betreffenden Drucker haben (durchaus verständlich) UND zweitens muß der aktive Benutzer auch Besitzer des Druckers sein. (Wenn der aktive NT-Benutzer "nur" Vollzugriff auf den Drucker hat und KEIN Besitzer ist, kann ich mit SetPrinter den DevMode-Teil von PRINTER_INFO_2 NICHT ändern !) Hierbei besteht jedoch schon das Problem, daß man den Besitz eines Druckers unter NT scheinbar nicht per Automatisierung (Script, etc.) setzen kann, so daß unsere Kunden mit NT jedesmal vor einem Druck in der Systemsteuerung den Besitz des Druckers übernehmen müssen.

    Meine beiden Fragen:

    1. Wie kann man den Besitz eines Druckers unter NT per Automatisierung
    übernehmen ???

    oder

    2. Wie kann man den DevMode-Teil der PRINTER_INFO_2 - Struktur erfolgreich
    ändern (unter NT) OHNE Besitzer des Druckers zu sein ?
    Der Vollzugriff auf den Drucker müßte doch reichen. Man kann doch auch
    ohne Besitzer zu sein, im Windows-Drucker-Setupdialog Änderungen an den
    Einstellungen vornehmen !

    Ich bin dankbar für jeden Tip !

    Branco Wassmuth

  • #2
    Hallo,

    tritt dieses Problem auch bei dem folgenden Zugriff auf?
    <pre>
    uses Printers, WinSpool;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    aDevice : array[0..255] of char;
    aDriver : array[0..255] of char;
    aPort : array[0..255] of char;
    hDMode : THandle;
    PDMode : PDEVMODE;
    begin
    Printer.PrinterIndex := -1;
    Printer.GetPrinter(aDevice, aDriver, aPort, hDMode);
    if hDMode <> 0 then begin
    pDMode := GlobalLock(hDMode);
    if pDMode <> nil then begin
    // A4
    pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE;
    pDMode^.dmPaperSize := DMPAPER_A4;
    { Druckerschacht (brother HL-1260)
    Automatische Auswahl (269)
    Oberer Papierschacht (1)
    Manuelle Papierzufuhr (4)
    Briefumschlag, Manuelle (6)
    Unterer Papierschacht (2)
    }
    pDMode^.dmFields := pDMode^.dmFields or DM_DEFAULTSOURCE;
    pDMode^.dmDefaultSource := DMBIN_MANUAL; //269;
    GlobalUnlock(hDMode);
    end;
    end;
    with Printer do
    begin
    PrinterIndex := Printer.PrinterIndex;
    BeginDoc;
    Canvas.TextOut(100,100, 'Aus welchem Schacht kommt dieses Blatt?');
    EndDoc;
    end;
    end;
    </pre&gt

    Comment


    • #3
      Hallo Herr Kosch,

      danke für die Antwort.
      Das Code-Beispiel von Ihnen funktioniert einwandfrei (egal, ob man Besitzer des Druckers ist oder nicht), da in diesem Beispiel NICHT der DevMode-Teil der PRINTER_INFO_2 - Struktur geändert wird !
      D.h. die Änderungen aus dem Beispiel sind auch nur temporär und werden nicht in die Druckereinstellungen im System zurückgeschrieben (d.h. man kann sie nicht im Drucker-Setup-Dialog der Systemsteuerung nachprüfen). Es gibt innerhalb von Windows ja scheinbar mehrere "Orte", an denen Druckereinstellungen in System gespeichert werden und das erleichtert die Sache nicht unbedingt.
      Ich brauche eine Möglichkeit die Druckereinstellungen in der PRINTER_INFO_2 - Struktur (WINSPOOL) zu ändern. (alles was hier erfolgreich geändert wird, läßt sich im Drucker-Setup-Dialog der Systemsteuerung nachprüfen). Die einzige Möglichkeit, die ich gefunden habe, um überhaupt die PRINTER_INFO_2 - Struktur zu ändern, ist die, die ich in meiner ersten Anfrage oben beschrieben habe.
      Die "SetPrinter" - Funktion aus WINSPOOL.PAS ändert aber die PRINTER_INFO_2 - Struktur NUR DANN erfolgreich, wenn ich Besitzer des entsprechenden Druckers bin !!!
      Was tue ich also, wenn ich KEIN Besitzer bin, sondern "nur" Vollzugriff habe ???
      Vielleicht haben Sie ja Zeit, um dies einmal zu testen.

      Gruß

      Branco Wassmuth

      PS: noch ein Hinweis: "Printer.GetPrinter" aus der Unit "PRINTERS" liefert unter Windows 95 einen leeren Druckertreiber und unter Windows NT einen leeren Druckertreiber UND einen leeren Druckeranschluß !! Dies ist laut Borland ein Delphi-BUG !!!
      Um Probleme mit "Printer.SetPrinter" zu vermeiden sollte vorher der Druckertreiber und der Druckeranschluß separat aus der Registry ermittelt werden

      Comment


      • #4
        Hat sich erledigt (hab's endlich selber rausgekriegt)

        Branc

        Comment


        • #5
          Und was wars??

          Comment


          • #6
            Das möchte ich auch wissen !!!

            Comment


            • #7
              Hi,

              hatte irgendwie den Eindruck, das interessiert keinen, daher hab ich die Lösung nicht dabei geschrieben...

              also hier die Lösung:

              Ich hatte ja schon lange die Vermutung, daß man die SERURITY_DESCRIPTOR - Struktur, die Teil der PRINTER_INFO_2 ist, ändern muß, um den Besitzer per Code einzustellen.
              (z. B. mit SetKernelObjectSecurity, SetSecurityDescriptorDacl, InitializeSecurityDescriptor, usw.)
              Aber alle meine Tests dazu haben nie funktioniert.

              Das genau war auch mein Denkfehler !

              Wenn man ganz normal mit "OpenPrinter", "GetPrinter" und "SetPrinter" aus WINSPOOL die Druckereinstellungen ändert, so versucht die Fkt. "SetPrinter" zusätzlich auch die SECURITY_DESCRIPTOR - Struktur zu ändern, auch wenn man das im Code gar nicht mit angegeben hat !!!!
              Das Ändern der SECURITY_DESCRIPTOR - Struktur wiederum funktioniert nur, wenn man Besitzer des Druckers ist !
              Da alle Änderungen nach dem Prinzip "alles oder nichts" gemacht werden, hat die Änderung der Druckereinstellungen auch nur dann funktioniert, wenn ich Besitzer des Druckers war.

              Die Lösung liegt in einer lächerlichen Zeile:

              Man muß einfach BEVOR man mit "SetPrinter" irgendwelche Einstellungen ändern will, explicit "sagen", daß man die SECURITY_DESCRIPTOR - Strukur NICHT AUCH ändern will.
              Dies macht man mit der folgenden Zeile:

              pi2.pSecurityDescriptor := nil;

              Vor dieser Zeile stehen, wie gesagt, alle Änderungen an der DEVMODE - Struktur und nach der Zeile steht direkt "SetPrinter".

              Und schon klappt's.

              Branc

              Comment

              Working...
              X