![]() |
Druckerstatus
Hallo zusammen,
habe mich nun fast durch die ganze DP gequält und nichts richtiges gefunden. Hat denn niemand eine neue Erkenntnis zum Druckerstatus? In meiner OLE Anwendung drucke ich im Hintergrund. Ist der Drucker nicht eingeschaltet gibt's ein Problem (blablabla... Systemkonfiguration überprüfen). Diese Meldung hätte ich gerne vor dem Hintergrunddruck mit einer sinnvollen Message abgefangen, damit der Anwender noch die Möglichkeit hat seinen Drucker einzuschalten, Papier nachzulegen usw. Nachdem der Anwender mit OK bestätigt, soll dann erst der Hintergrunddruck erfolgen, vorausgesetzt es klappt dann, ansonsten wieder Meldung. Eigentlich müßte das was ich machen möchte doch ganz einfach sein MS merkt doch auch, daß was nicht stimmt, sonst käme ja die Meldung nicht! Gruß Christoph |
Re: Druckerstatus
Die Funktion GetPrinter() mit dem Level 6 aufrufen. Dazu wird die Struktur
PRINTER_INFO_6 (in Unit WinSpool)benötigt. |
Re: Druckerstatus
Huch, hab sowas noch nicht gemacht, wie rufe ich denn so eine Funktion auf?
|
Re: Druckerstatus
Siehe:
![]() In diesem Sourcecode wird mit Level 2 gearbeitet und mit Level 2 erhältst du weit mehr Infos als du eigentlich brauchst. Der Druckerstatus steckt im Feld "Status". |
Re: Druckerstatus
Also, hier geht es ja richtig in die Windows Programmierung. Ich arbeite mit Win98, Printer_Info_6 ist aber für Windows NT.
Habe ich das richtig verstanden, wenn ich die Printer_Info_2 verwende muß ich nur den Status abfragen? Doch was kann ich daraus interpretieren? So ganz ist mir das noch nicht klar. Hat Delphi selbst keine Möglichkeit? |
Re: Druckerstatus
Zitat:
Siehe PRINTER_STATUS_PAUSED, PRINTER_STATUS_WAITING, ... Zitat:
unzureichend und auch QuickReport ist voller Bugs. |
Re: Druckerstatus
Hallo Shima,
erst mal vielen Dank für Deine Hilfe. Leider komme ich mit meinem Problem trotzdem nicht weiter. Habe mich nun die ganzen letzten Tage damit rumgeschlagen. Wahrscheinlich reichen meine Kenntnisse dafür einfach noch nicht aus.
Delphi-Quellcode:
Vielleicht kannst Du mir mal eine kleinen Lehrgang erteilen oder sagen was ich alles machen muß.
// WinWord starten
try MSWord := CreateOleObject('Word.Application'); except ShowMessage('Ich kann Microsoft Word nicht starten.'); end; // WinWord anzeigen nur für Testzwecke := true MSWord.Visible := false; MSWord.Documents.Open(FileName:=Verzeichnis + '\' + 'Standard-Serienbrief.doc'); MSWord.ActiveDocument.MailMerge.OpenDataSource (Name:=Verzeichnis + '\' + 'SelAdressen.txt'); MSWord.Selection.Font.Name := 'Times New Roman'; MSWord.Selection.Font.Size := 12; if Anzahl <> 0 then begin MSWord.ActiveDocument.MailMerge.Destination := 0; MSWord.ActiveDocument.MailMerge.MailAsAttachment := False; MSWord.ActiveDocument.MailMerge.MailAddressFieldName := ''; MSWord.ActiveDocument.MailMerge.MailSubject := ''; MSWord.ActiveDocument.MailMerge.SuppressBlankLines := True; for I := 1 to Anzahl do begin MSWord.ActiveDocument.MailMerge.DataSource.FirstRecord := 1; MSWord.ActiveDocument.MailMerge.DataSource.LastRecord := -16; end; MSWord.ActiveDocument.MailMerge.Execute; end; // Ausdrucken >>>>> Hier möchte ich gerne prüfen, ob der Drucker bereit ist <<<<<< MSWord.Application.PrintOut(Background := false, Range := 0, Item := 0, Copies := 1, PageType := 0); //Dateien schließen MSWord.Documents.Close(SaveChanges := 0); //MSWord schließen MSWord.Application.Quit; MSWord := Unassigned; Gruß Christoph [edit=Matze][delphi]-Tags repariert. Mfg, Matze[/edit] |
Re: Druckerstatus
Du kannst eigentlich auf den Windows-Spooler vertrauen:
dieser sorgt dafür, dass Dokumente ausgedruckt werden, sobald der Drucker zum Druck bereit wird. Dies funktioniert auch nach einem Reboot. Du möchtest wahrscheinlich verhindern, dass ein Benutzer viele Druckjobs absetzt, der Drucker aber nicht bereit ist. Im Extremfall könnte so die Arbeiten von Stunden verlorengehen. Dann wäre es doch ratsamer, nur zu Prüfen, wieviele Druckaufträge gerade im Spooler sind. Sind mehr als 3 Druckaufträge vorhanden dann bringt dein Programm diese Meldung: Zitat:
Delphi-Quellcode:
Jetzt bleibt nur noch das Problem, den aktuell eingestellten Druckername von WinWord
var
info :TPrinterInfo2Easy; begin GetPrinterInfo2(druckername,info); // aus Code-Library; siehe Link aus früherem Posting if info.cJobs > 3 then begin // Meldung ausgeben if MessageDlg(Format('Es sind %d Druckaufträge im Spooler für Drucker "%s".'#13#10, [info.cJobs, info.PrinterName])+ 'Wollen Sie einen weiteren Auftrag hinzufügen ?', mtConfirmation, [mbOK, mbCancel], 0) = mrCancel then Abort; end; zu ermitteln. Das wäre aber eine eigene Frage. |
Re: Druckerstatus
So, ich hab es mal versucht, aber irgend etwas paßt da wohl noch nicht.
Eigentlich will ich nur den Anwender darauf hinweisen seinen Drucker einzuschalten und hatte nun angenommen das über den Status zu erreichen. Ich habe Dir einmal die Inhalte zusammengestellt:
Delphi-Quellcode:
Info.ServerName ''
Info.PrinterName 'EPSON Stylus DX5000 Series' Info.ShareName '' Info.PortName 'EPUSB1:' Info.DriverName 'EPSON Stylus DX5000 Series' Info.Comment '' Info.Location '' Info.SepFile '' Info.PrintProcessor 'EPSON Color Print Processor(70)' Info.Datatype 'RAW' Info.Parameters '' Info.Attributes '2116' Info.Priority '1' Info.DefaultPriority '0' Info.StartTime '0' Info.UntilTime '0' Info.Status '0' Info.cJobs '0' Info.AveragePPM '0' Info.Status und Info.cJobs sind immer gleich '0', ob der Drucker nun eingeschaltet ist oder nicht. Wie gesagt, ich möchte nur den Anwender dazu veranlassen seinen Drucker anzuschalten. Nach Bestätigung versuche ich den Ausdruck noch einmal, klappte es ist's gut, wenn nicht neue Message. |
Re: Druckerstatus
Moin,
der Info.Status ist bei mir auch immer gleich 0. Info.cJobs gibt die Anzahl der aktuellen Druckaufträge an, das funktioniert bei mir jedoch. Folgender Code funktioniert zumindest bei mir unter Win98 mit meinem Drucker:
Delphi-Quellcode:
Ob das immer funktioniert ist natürlich eine andere Sache. Der Code musste ansonsten wohl noch etwas überarbeitet werden.
procedure TForm1.Button1Click(Sender: TObject);
var Needed: DWORD; Device, Driver, Port : array[0..200] of char; hPrinter, hDeviceMode : THandle; Buffer : Pointer; hDevice: cardinal; begin Printer.PrinterIndex := -1; Printer.GetPrinter(Device, Driver, Port, hDeviceMode); if WinSpool.OpenPrinter(@Device, hPrinter, nil) then begin GetPrinter(hPrinter, 2, nil, 0, @Needed); GetMem(Buffer, Needed); if GetPrinter(hPrinter, 2, Buffer, Needed, @Needed) then if TPrinterInfo2A(Buffer^).pPortName <> nil then begin hDevice:= CreateFile(PChar('\\.\'+TPrinterInfo2A(Buffer^).pPortName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); if hDevice <> INVALID_HANDLE_VALUE then begin CloseHandle(hDevice); Showmessage('Der Drucker ist online.'); end else Showmessage('Der Drucker ist offline.') end; FreeMem(Buffer, Needed); WinSpool.ClosePrinter(hPrinter); end; end; |
Re: Druckerstatus
Hallo zusammen,
wußte garnicht, daß ich mit dem Drucker so'ne Lawine lostrete. Anscheinend ist das Problem Drucker aber garnicht so trivial. Hallo bisetter, habe Deine Routine mal bei mir eingebaut. Eine kleine Änderung mußte ich vornehmen: if WinSpool.OpenPrinter(@Device, hPrinter, nil) then geändert in if WinSpool.OpenPrinter(Device, hPrinter, nil) then sonst gibt es einen Fehler : Incompatible Typen: 'Array' und 'Char'. Bei der entscheidenden Abfrage erhalte ich immer folgendes: if hDevice <> INVALID_HANDLE_VALUE then hDevice = '4294967295' INVALID_HANDLE_VALUE = '4294967295' also ist der Drucker immer offline. Was kann ich denn jetzt noch machen? |
Re: Druckerstatus
Hallo,
den Code habe ich jetzt mit dem selben Drucker unter WinXP getestet, dort funktionierte er jedoch auch nicht. Das man mit CreateFile unter Win98 jedoch nicht unter WinXP auf den Drucker zugreifen kann, haben wohl auch schon andere Leute festgestellt. Wenn der Code bei dir unter Win98 nicht geht, dann wird es wohl nicht mit allen Druckern funktionieren. :( |
Re: Druckerstatus
Interessanter als der Wert des Handles waere was GetLastError() zurueckgibt. Ich vermute mal, dass einer der Parameter CreateFile() nicht schmeckt, denn prinzipiell kann man Symlinks auf Geraete unter XP (und NT4/2000/2003 ...) sehr wohl per CreateFile() oeffnen. Uebrigens eine nette Analogie zu Linux' "/dev"-Verzeichnis ;)
Im uebrigen braucht man einen Printermonitor (ja, das heisst so) um einen Druckjob zu unterbinden (falls das wirklich das Ziel ist) - es sei denn das Drucken selber (und die Statusabfrage) soll aus deinem eigenen Programm heraus erfolgen. Nichtmal ![]() Uebrigens ist die Sinnhaftigkeit des Druckerstatus umstritten und haengt sehr stark davon ab was der Drucker zurueckmeldet, bzw. zurueckmelden kann. Das muss nicht unbedingt immer sinnvoll sein. |
Re: Druckerstatus
Zitat:
Delphi-Quellcode:
gibt bei mir WinXP die Nachricht "Das System kann die angegebene Datei nicht finden" aus.
ShowMessage(SysErrorMessage(GetLastError));
|
Re: Druckerstatus
Zitat:
|
Re: Druckerstatus
Na, nun mal wieder zum Thema:
Keiner mehr da, dem noch etwas einfällt, was ich nun mit meinem Problem machen könnte? Gruß Christoph |
Re: Druckerstatus
Zitat:
@bitsetter: Mich wuerde mal der Wert fuer TPrinterInfo2A(Buffer^).pPortName interessieren, den ihr bekommt. |
Re: Druckerstatus
Hallo Olli
in dem Feld steht bei mir 'EPUSB1:', dasselbe wie im Info.PortName. Ich habe einen EPSON Stylus DX5000 Series an USB1 angeschlossen. Zu Deiner Antwort: Ja, ich möchte die Lösung in meinem Programm vornehmen. Nein, die obige Lösung bringt immer 'Drucker ist offline' weil die Vergleichswerte identisch sind. :shock: Monitor??? , - mache Delphi erst seit 4 Monaten !!! Gruß Christoph |
Re: Druckerstatus
Zitat:
Zitat:
|
Re: Druckerstatus
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Mit dem Tool WinObj konnte ich jedoch keinen ähnlichen Namen finden, im Bild ist ein Auszug davon. |
Re: Druckerstatus
Hallo Olli,
Sysinternals bei Microsoft.com? Ist das auch für Win98, ich habe nur Win98. Gruß Christoph |
Re: Druckerstatus
Zitat:
OT: Auch ein WM-Fan, wie ich sehe?! Auch Eule-Leser? :stupid: Zitat:
Zitat:
![]() |
Re: Druckerstatus
Also ich versuch's nochmal :|
Man braucht nicht zu prüfen, ob der Drucker online und bereit ist; das erledigt schon Windows. Man sollte nur prüfen, ob zu viele Druckaufträge im Spooler liegen. Der Benutzer könnte ja auch einen Laptop haben. In der Dockingstation kann er normal drucken da dort ein Drucker angeschlossen ist. Unterwegs kann er nicht drucken, aber das ist kein Problem, der Spooler druckt, sobald der Rechner in der Dockingstation ist. Ansonsten: Immer zuerst mit GetPrinter() den Level 6 abfragen, sollte das misslingen (Returnwert prüfen), dann erfolgt ein Fallback auf Level 2. |
Re: Druckerstatus
Zitat:
1. Manche Drucker haben genug Speicher um hunderte Seiten Text mit ein paar Fontinfos aufzunehmen. Sobald es also an den Drucker geschickt ist, waere damit deine Methode zum Scheitern verdammt. 2. Handelt es sich um einen Drucker welcher auf die eine oder andere Weise an einem Printserver angeschlossen ist, ist die Einschätzung ob die Druckerwarteschlange voll ist oder nicht garnicht so einfach zu treffen. |
Re: Druckerstatus
Hallo zusammen,
ich habe mir das mit dem 'EPUSB1:' noch einmal genauer angesehen. In Drucker/Einstellungen/Details steht bei mir bei nicht eingeschaltetem Drucker: EPUSB1: (USB-Schnittstelle nicht angeschlossen) Bei eingeschaltetem Drucker: EPUSB1: (EPSON Stylus DX5000) Ich nehme an, daß bei seriellen oder parallelen Anschlüssen die o.g. Routine funktioniert, nicht aber bei Abschlüssen über USB. Vielleicht würde ich mit meinem Problem weiterkommen, wenn mir jemand sagen könnte, wie ich den Anschluß zusätzlich zu den eventuellen Druckermeldungen prüfen könnte. Es hat ja nicht jeder einen Drucker über USB angeschlossen. In meiner Anwendung müßte ich halt alle eventuell möglichen Anschlüsse überprüfen können. Gruß Christoph |
Re: Druckerstatus
Okay, habe zufaellig, da ich mich mal wieder in Dtl. aufhalte, einen USB-Drucker. Wenn ich es schaffe, schaue ich da mal heute im Laufe des Abends rein. Ansonsten muss es warten. Limit ist in knapp 2 Wochen, dann geht's zurueck ;)
|
Re: Druckerstatus
Hi,
Zitat:
Unter WinXP konnte ich mit diesem \\?\USB#Vid_04a9&Pid_1062#6013TT#{28d78fad-5a12-11d1-ae5b-0000f803a8c2} Wert testen ob mein Drucker offline ist. Den hatte ich mit Regmon herausgefunden, wenn ich den USB Stecker vom Drucker reingesteckt bzw rausgezogen hatte. Das ist übrigens einer der Werte den auch das Tool WinObj angezeigt hatte. Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz