![]() |
Druckaufträge überwachen und Programm starten
Hi,
nach langem suchen ( drei Tage ) stelle ich nun meine Frage hier mal! Ich möchte folgendes machen und zwar, soll das Programm den Druckerspooler von Windows überwachen und sobald ein Druckauftrag gesendet worden ist Programm bzw. ein Telnet befehl an die Fritzbox gesendet werden. Mein Hauptproblem liegt beim überwachen des Spoolers! WinAPI? Desweiteren Telnet einloggen bei der Fritzbox und einen Telnet befehl ausführen! Dieser Befehl schaltet dann die Steckdose an und somit den Drucker!!! Bin um jede Hilfe dankbar Gruß Olli |
AW: Druckaufträge überwachen und Programm starten
Hi,
Zitat:
![]() Axel |
AW: Druckaufträge überwachen und Programm starten
Das bringt leider gar nichts, gibt es ne möglichkeit das mein Programm auf eine Windows Massage reagiert ohne das ich eine Timer abfrage machen muss? Ich könnte zwar einfach einen Timer nehmen der ständig die Drucker warte schlange überprüft, aber ich weiß nicht in wie fern das System dadurch belasted wird! Oder kann ich es vernachlässigen?
Gruß Olli |
AW: Druckaufträge überwachen und Programm starten
Hi Olli,
Zitat:
Zitat:
Axel |
AW: Druckaufträge überwachen und Programm starten
Guck dir hier mal
![]() |
AW: Druckaufträge überwachen und Programm starten
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
ohne erweiterte, präzise Kenntnis der zahlreichen benötigten Parameter ist nicht ganz so einfach, wie unterstellt wird. Insbesondere für die von Oliver1983 beschriebene Aufgabe des permannten Pollings. Vielleicht entspricht dies hier Deinen Vorstellungen (Source und Bin (D7, für Screen 1280x1024 compiliert)): cf. Anhang. Der PrintSpooler wird ein einem eigenen Thread überwacht, so dass der Mainthread nicht blockiert ist. Der Spoolerthreat gibt über eine userdefinierte Message an den Mainthreat die Information, sobald ein neuer Printjob im Spooler vorliegt. Der Mainthread kann dann mit dieser Information anfangen (in der Message-Methode WM_SpoolerStatus()), was gebraucht wird. Den Spoolermonitor könnte man noch - je nach Bedarf - erheblich erweitern um Rückmeldungen an den Mainthreat, z.B.: - welcher Drucker mit dem Job beauftragt worden ist - welches Dokument gedruckt werden soll - falls ein Job aus dem Spooler entfernt worden ist usw. |
AW: Druckaufträge überwachen und Programm starten
@ASM
ist schon cool! Aber sobald ich das mit DelphiXE Compiliere habe ich ne CPU Auslastung von 25%, nehme ich aber die aus der ZIP Datei ist alles super!!! Warum? Gruß Olli |
AW: Druckaufträge überwachen und Programm starten
Zitat:
Mein Source und das entspr. Compilat ist unter Delphi 7 entstanden. Ich habe mein Projekt jetzt auch einmal selbst unter Delphi XE (2010) compiliert: zunächst einmal muss dazu in der Unit SpoolerStatusThreat obligat eine kleine Änderung vorgenommen werden. Es muss der Ergebnistyp der Funktion GetCurrentPrinterName() von "AnsiString" auf "String" (= Widestring) umgestellt werden. Außerdem muss in der Prozedur WatchSpoolerStatus die Anweisung auf pi2.pPrinterName := PWideChar(GetCurrentPrinterName); geändert werden. Wichtig: Wird der Funktionstyp unter Delphi XE nicht von AnsiString auf WideString abgeändert, so versagt das komplette Monitoring. Mein Test mit den lauffähigen Programmen: Compiliert unter D7: Auslastung der CPU unter WinXP (SP3): beginnt bei 0,12% geht dann allmählich runter auf 0,08% Compiliert unter Delphi XE: Auslastung der CPU unter WinXP (SP3): steigt bei beginn des Monitoring (START-Button) auch bei mir schnell auf ca.50% !! Erfolgreiche Korrektur: In der Unit SpoolerStatusThreat, Prozedur WatchSpoolerStatus die Repeat-Schleife durch Einfügen eines sleep(10) so bremsen, dass der Prozessor nicht permanent mit Taktzyklen überlastet wird. Das Monitoring bleibt trotzdem voll funktionsfähig erhalten. Also den Code in der Unit SpoolerStatusThreat für Delphi XE unbedingt ändern auf:
Code:
Das Ergebnis nach Änderung:
repeat
sleep(10); // Pause von 10 Millisekunden neu eingefügt PeekMessage(aMsg, 0, 0, 0, PM_REMOVE); AppTerminated := (aMsg.message = WM_QUIT); until AppTerminated or (WaitForSingleObject(hResult, 500) = WAIT_OBJECT_0); Compiliert unter Delphi XE, getestet unter WinXP (SP3) auf einem 3 GHz Rechner : Auslastung der CPU nach Beginn des Monitoring beginnt bei 1-2% , sinkt dann rasch ab auf eine Auslastung unter 0,1%. Gruß, ASM |
AW: Druckaufträge überwachen und Programm starten
Zitat:
Zitat:
Zitat:
|
AW: Druckaufträge überwachen und Programm starten
so hab ich mal gemacht die änderungen, aber ich bekomme immer ne fehlermeldung "Zugriffsverletzung in der ntdll.dll"!
hier mal die spoolerStatusThread Unit:
Delphi-Quellcode:
25.08.2011 - 14:08
unit SpoolerStatusThreat;
interface uses Classes, Windows, Messages, SysUtils, Graphics, StdCtrls, Forms; type TSpoolerMonitor = class(TThread) private FMsg: string; FForm: TForm; protected procedure Execute; override; procedure SpoolerStatus; public constructor Create(Suspend: boolean); overload; constructor Create(Suspend: boolean; Dispatch2Target: TForm); overload; public procedure exitThread; end; var SpoolerMonitor: TSpoolerMonitor; const WM_PRINTJOB_ADDED = WM_USER + 1000; implementation uses WinSpool, Printers; type TPrinterDevice = class Driver: string; Device: string; Port: string; end; Var pi2: PRINTER_INFO_2; pno: PRINTER_NOTIFY_OPTIONS; pinfo: PPrinterNotifyInfo; pn: array[0..1] of PRINTER_NOTIFY_OPTIONS_TYPE; pnf: array[0..100] of WORD; jnf: array[0..100] of WORD; function GetCurrentPrinterName: String; begin Result := TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]).Device; end; procedure TSpoolerMonitor.SpoolerStatus; var hResult: THandle; Result: LongBool; hPrinter: cardinal; pdwChange: DWORD; ok: boolean; AppTerminated: Boolean; aMsg: TMsg; begin pdwChange := 0; pi2.pPrinterName := PWideChar(GetCurrentPrinterName); if OpenPrinter(pi2.pPrinterName, hPrinter, 0) then hResult := FindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_JOB, 0, @pno); ok:= hResult <> INVALID_HANDLE_VALUE; if ok then while not terminated do begin AppTerminated := false; repeat sleep(10); // Pause von 10 Millisekunden neu eingefügt PeekMessage(aMsg, 0, 0, 0, PM_REMOVE); AppTerminated := (aMsg.message = WM_QUIT); until AppTerminated or (WaitForSingleObject(hResult, 500) = WAIT_OBJECT_0); if AppTerminated then exit; ok := false; pno.Flags := 0; Result := FindNextPrinterChangeNotification(hResult, pdwChange, @pno, pointer(pinfo)); if ord(Result) <> 0 then begin if (pdwChange and PRINTER_CHANGE_ADD_JOB) > 0 then PostMessage(fForm.Handle, WM_PRINTJOB_ADDED, 0, 0); end; end; end; constructor TSpoolerMonitor.Create(Suspend: boolean); begin inherited Create(Suspend); FreeOnTerminate := True; end; constructor TSpoolerMonitor.Create(Suspend: boolean; Dispatch2Target: TForm); begin inherited Create(Suspend); FreeOnTerminate := True; FForm := Dispatch2Target; end; procedure TSpoolerMonitor.Execute; var aMsg: TMsg; begin inherited; SpoolerStatus; end; procedure TSpoolerMonitor.exitThread; begin PostThreadMessage(Self.ThreadID, WM_QUIT, 0, 0); if Suspended then Resume; end; initialization pno.Version := 2; pno.Flags := PRINTER_NOTIFY_OPTIONS_REFRESH; pno.Count := 200; pno.pTypes := @pn; pn[0].wType := PRINTER_NOTIFY_TYPE; pn[0].Count := 8; pn[0].pFields := @pnf; pn[1].wType := JOB_NOTIFY_TYPE; pn[1].Count := 24; pn[1].pFields := @jnf; pnf[0] := PRINTER_NOTIFY_FIELD_STATUS; pnf[1] := PRINTER_NOTIFY_FIELD_CJOBS; pnf[2] := PRINTER_NOTIFY_FIELD_ATTRIBUTES; pnf[3] := PRINTER_NOTIFY_FIELD_COMMENT; pnf[4] := PRINTER_NOTIFY_FIELD_DEVMODE; pnf[5] := PRINTER_NOTIFY_FIELD_LOCATION; pnf[6] := PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR; pnf[7] := PRINTER_NOTIFY_FIELD_SEPFILE; jnf[0] := JOB_NOTIFY_FIELD_DOCUMENT; jnf[1] := JOB_NOTIFY_FIELD_STATUS; jnf[2] := JOB_NOTIFY_FIELD_MACHINE_NAME; jnf[3] := JOB_NOTIFY_FIELD_PORT_NAME; jnf[4] := JOB_NOTIFY_FIELD_USER_NAME; jnf[5] := JOB_NOTIFY_FIELD_NOTIFY_NAME; jnf[6] := JOB_NOTIFY_FIELD_DATATYPE; jnf[7] := JOB_NOTIFY_FIELD_PRINT_PROCESSOR; jnf[8] := JOB_NOTIFY_FIELD_PARAMETERS; jnf[9] := JOB_NOTIFY_FIELD_DRIVER_NAME; jnf[10] := JOB_NOTIFY_FIELD_DEVMODE; jnf[11] := JOB_NOTIFY_FIELD_STATUS_STRING; jnf[12] := JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR; jnf[13] := JOB_NOTIFY_FIELD_PRINTER_NAME; jnf[14] := JOB_NOTIFY_FIELD_PRIORITY; jnf[15] := JOB_NOTIFY_FIELD_POSITION; jnf[16] := JOB_NOTIFY_FIELD_SUBMITTED; jnf[17] := JOB_NOTIFY_FIELD_START_TIME; jnf[18] := JOB_NOTIFY_FIELD_UNTIL_TIME; jnf[19] := JOB_NOTIFY_FIELD_TIME; jnf[20] := JOB_NOTIFY_FIELD_TOTAL_PAGES; jnf[21] := JOB_NOTIFY_FIELD_PAGES_PRINTED; jnf[22] := JOB_NOTIFY_FIELD_TOTAL_BYTES; jnf[23] := JOB_NOTIFY_FIELD_BYTES_PRINTED; end. Hat sich grad erledigt, hab noch mal den Source aus der Zip genommen klappt jetzt und CPU auslastung ist jetzt bei 0% gut so :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:30 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