Solved

print spooler job access!

Posted on 2001-07-04
10
1,000 Views
Last Modified: 2010-04-06
I'm actually looking for a way to intercept a document send in the spooler via delphi's code.

The large part of my problem is that some printers don't save print job to the hard drive.  There's an API call (FindFirstPrinterChangeNotification [winspool]) that i can use.  But i've tried it and it seems that it's looking in the spool directory if there's a new job added to the spooler.  Like i've said, some printer don't save a file to the hard drive, i need a way to capture all the data of the print  jobs not saved to the drive.

Do anybody know how to get the information directly from the spooler?

Thank you!
0
Comment
Question by:M_AR
10 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 6253873
I'm not sure what you want but this code shows the job status:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
    procedure WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS);
      message WM_SPOOLERSTATUS;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS);
begin
  Label1.Caption := IntToStr(msg.JobsLeft) + ' Jobs currenly in spooler';
  msg.Result := 0;
end;
0
 
LVL 13

Accepted Solution

by:
Epsylon earned 75 total points
ID: 6253908
Found this code on google. Sorry for the awfull layout:

procedure TForm1.Button1Click(Sender: TObject);

   const
     MaxJobs = 1024;
   type
     TArrayofJobs = array[1..1024] of TJobInfo2;
   var
     NumJobs : integer;
     pcbNeed,pcReturned:DWord;
     i : integer;
     Device : array[0..255] of char;
     Driver : array[0..255] of char;
     Port   : array[0..255] of char;
     hPrinter: THandle;
     hDeviceMode: THandle;
     Buffer: Pointer;
     TmpWinDir : array[0..255] of Char;
     Windir : string;
     Inputfile : textfile;
     line : string;

   begin
     if GetWindowsDirectory(TmpWinDir, sizeof(TmpWinDir)) <> 0 then
       Windir := Strpas(TmpWinDir) + '\SPOOL\PRINTERS\'
     else
       Windir := 'C:\WINDOWS\SPOOL\PRINTERS\';

     Printer.PrinterIndex := ListBox2.itemindex;
     Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
     if not WinSpool.OpenPrinter(@Device, hPrinter, nil) then exit;

     ListBox1.items.clear;
     ListBox1.items.add('Windir :='+WinDir);
     GetPrinter(hPrinter, 2, nil,0,@pcbNeed);  // return false, Don't Care
     GetMem(Buffer, pcbNeed);
     if GetPrinter(hPrinter, 2, Buffer, pcbNeed, @pcbNeed) then
       begin
         if TPrinterInfo2A(Buffer^).pServerName <> nil then

ListBox1.items.add('pServerName='+TPrinterInfo2A(Buffer^).pServerName);
         if TPrinterInfo2A(Buffer^).pPrinterName <> nil then

ListBox1.items.add('pPrinterName='+TPrinterInfo2A(Buffer^).pPrinterName);
         if TPrinterInfo2A(Buffer^).pShareName <> nil then

ListBox1.items.add('pShareName='+TPrinterInfo2A(Buffer^).pShareName);
         if TPrinterInfo2A(Buffer^).pComment <> nil then

ListBox1.items.add('pComment='+TPrinterInfo2A(Buffer^).pComment);
         if TPrinterInfo2A(Buffer^).pLocation <> nil then

ListBox1.items.add('pLocation='+TPrinterInfo2A(Buffer^).pLocation);
         if TPrinterInfo2A(Buffer^).pPortName <> nil then

ListBox1.items.add('pPortName='+TPrinterInfo2A(Buffer^).pPortName);
         if TPrinterInfo2A(Buffer^).pDriverName <> nil then

ListBox1.items.add('pDriverName='+TPrinterInfo2A(Buffer^).pDriverName);
         if TPrinterInfo2A(Buffer^).pSepFile <> nil then
         
ListBox1.items.add('pSepFile='+TPrinterInfo2A(Buffer^).pSepFile);
         if TPrinterInfo2A(Buffer^).pPrintProcessor <> nil then

ListBox1.items.add('pPrintProcessor='+TPrinterInfo2A(Buffer^).pPrintProcessor);
         if TPrinterInfo2A(Buffer^).pDatatype <> nil then

ListBox1.items.add('pDatatype='+TPrinterInfo2A(Buffer^).pDatatype);
         if TPrinterInfo2A(Buffer^).pParameters <> nil then

ListBox1.items.add('pParameters='+TPrinterInfo2A(Buffer^).pParameters);

ListBox1.items.add('Attributes='+inttostr(TPrinterInfo2A(Buffer^).Attributes
));
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_QUEUED
= PRINTER_ATTRIBUTE_QUEUED then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_QUEUED');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_QUEUED
= PRINTER_ATTRIBUTE_QUEUED then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_QUEUED');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_DIRECT
= PRINTER_ATTRIBUTE_DIRECT then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_DIRECT');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_DEFAULT
= PRINTER_ATTRIBUTE_DEFAULT then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_DEFAULT');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_SHARED
= PRINTER_ATTRIBUTE_SHARED then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_SHARED');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_NETWORK
= PRINTER_ATTRIBUTE_NETWORK then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_NETWORK');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_HIDDEN
= PRINTER_ATTRIBUTE_HIDDEN then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_HIDDEN');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_LOCAL =
PRINTER_ATTRIBUTE_LOCAL then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_LOCAL');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_ENABLE_DEVQ = PRINTER_ATTRIBUTE_ENABLE_DEVQ then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_ENABLE_DEVQ');
         if TPrinterInfo2A(Buffer^).Attributes and
PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS = PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS
then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS');
         if TPrinterInfo2A(Buffer^).Attributes and PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST = PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST
then
           ListBox1.items.add('PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST');
         if TPrinterInfo2A(Buffer^).Attributes and PRINTER_ATTRIBUTE_WORK_OFFLINE = PRINTER_ATTRIBUTE_WORK_OFFLINE then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_WORK_OFFLINE');
         if TPrinterInfo2A(Buffer^).Attributes and PRINTER_ATTRIBUTE_ENABLE_BIDI = PRINTER_ATTRIBUTE_ENABLE_BIDI then
           ListBox1.items.add('  PRINTER_ATTRIBUTE_ENABLE_BIDI');

ListBox1.items.add('Priority='+inttostr(TPrinterInfo2A(Buffer^).Priority));

ListBox1.items.add('DefaultPriority='+inttostr(TPrinterInfo2A(Buffer^).DefaultPriority));

ListBox1.items.add('StartTime='+inttostr(TPrinterInfo2A(Buffer^).StartTime))
;

ListBox1.items.add('UntilTime='+inttostr(TPrinterInfo2A(Buffer^).UntilTime))
;

ListBox1.items.add('Status='+inttostr(TPrinterInfo2A(Buffer^).Status));
         if TPrinterInfo2A(Buffer^).Status and PRINTER_STATUS_PAUSED =
PRINTER_STATUS_PAUSED then
           ListBox1.items.add('  PRINTER_STATUS_PAUSED');
         if TPrinterInfo2A(Buffer^).Status and PRINTER_STATUS_ERROR =
PRINTER_STATUS_ERROR then
           ListBox1.items.add('  PRINTER_STATUS_ERROR');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_PENDING_DELETION = PRINTER_STATUS_PENDING_DELETION then
           ListBox1.items.add('  PRINTER_STATUS_PENDING_DELETION');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_PAPER_JAM =
PRINTER_STATUS_PAPER_JAM then
           ListBox1.items.add('  PRINTER_STATUS_PAPER_JAM');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_PAPER_OUT =
PRINTER_STATUS_PAPER_OUT then
           ListBox1.items.add('  PRINTER_STATUS_PAPER_OUT');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_MANUAL_FEED =
PRINTER_STATUS_MANUAL_FEED then
           ListBox1.items.add('  PRINTER_STATUS_MANUAL_FEED');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_PAPER_PROBLEM
= PRINTER_STATUS_PAPER_PROBLEM then
           ListBox1.items.add('  PRINTER_STATUS_PAPER_PROBLEM');
         if TPrinterInfo2A(Buffer^).Status and PRINTER_STATUS_OFFLINE
=
PRINTER_STATUS_OFFLINE then
           ListBox1.items.add('  PRINTER_STATUS_OFFLINE');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_IO_ACTIVE =
PRINTER_STATUS_IO_ACTIVE then
           ListBox1.items.add('  PRINTER_STATUS_IO_ACTIVE');
         if TPrinterInfo2A(Buffer^).Status and PRINTER_STATUS_BUSY =
PRINTER_STATUS_BUSY then
           ListBox1.items.add('  PRINTER_STATUS_BUSY');
         if TPrinterInfo2A(Buffer^).Status and PRINTER_STATUS_PRINTING
=
PRINTER_STATUS_PRINTING then
           ListBox1.items.add('  PRINTER_STATUS_PRINTING');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_OUTPUT_BIN_FULL = PRINTER_STATUS_OUTPUT_BIN_FULL then
           ListBox1.items.add('  PRINTER_STATUS_OUTPUT_BIN_FULL');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_NOT_AVAILABLE
= PRINTER_STATUS_NOT_AVAILABLE then
           ListBox1.items.add('  PRINTER_STATUS_NOT_AVAILABLE');
         if TPrinterInfo2A(Buffer^).Status and PRINTER_STATUS_WAITING
=
PRINTER_STATUS_WAITING then
           ListBox1.items.add('  PRINTER_STATUS_WAITING');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_PROCESSING =
PRINTER_STATUS_PROCESSING then
           ListBox1.items.add('  PRINTER_STATUS_PROCESSING');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_INITIALIZING =
PRINTER_STATUS_INITIALIZING then
           ListBox1.items.add('  PRINTER_STATUS_INITIALIZING');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_WARMING_UP =
PRINTER_STATUS_WARMING_UP then
           ListBox1.items.add('  PRINTER_STATUS_WARMING_UP');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_TONER_LOW =
PRINTER_STATUS_TONER_LOW then
           ListBox1.items.add('  PRINTER_STATUS_TONER_LOW');
         if TPrinterInfo2A(Buffer^).Status and PRINTER_STATUS_NO_TONER
=
PRINTER_STATUS_NO_TONER then
           ListBox1.items.add('  PRINTER_STATUS_NO_TONER');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_PAGE_PUNT =
PRINTER_STATUS_PAGE_PUNT then
           ListBox1.items.add('  PRINTER_STATUS_PAGE_PUNT');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_USER_INTERVENTION = PRINTER_STATUS_USER_INTERVENTION
then
           ListBox1.items.add('  PRINTER_STATUS_USER_INTERVENTION');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_OUT_OF_MEMORY
= PRINTER_STATUS_OUT_OF_MEMORY then
           ListBox1.items.add('  PRINTER_STATUS_OUT_OF_MEMORY');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_DOOR_OPEN =
PRINTER_STATUS_DOOR_OPEN then
           ListBox1.items.add('  PRINTER_STATUS_DOOR_OPEN');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_SERVER_UNKNOWN
= PRINTER_STATUS_SERVER_UNKNOWN then
           ListBox1.items.add('  PRINTER_STATUS_SERVER_UNKNOWN');
         if TPrinterInfo2A(Buffer^).Status and
PRINTER_STATUS_POWER_SAVE =
PRINTER_STATUS_POWER_SAVE then
           ListBox1.items.add('  PRINTER_STATUS_POWER_SAVE');

ListBox1.items.add('cJobs='+inttostr(TPrinterInfo2A(Buffer^).cJobs));

ListBox1.items.add('AveragePPM='+inttostr(TPrinterInfo2A(Buffer^).AveragePPM
));
       end;
     FreeMem(Buffer, pcbNeed);

     EnumJobs(hPrinter, 0, NumJobs, 2, nil, 0, pcbNeed, pcReturned);
     GetMem(Buffer, pcbNeed);
     if EnumJobs(hPrinter, 0, NumJobs, 2, Buffer, pcbNeed, pcbNeed,
pcReturned) then
       begin
         ListBox1.items.add('enumjobs ='+inttostr(pcReturned));
         for i := 1 to pcReturned do
           begin
             ListBox1.items.add('----------------------------------');

ListBox1.items.add('JobId='+inttostr(TArrayofJobs(buffer^)[i].JobId));
             if TarrayofJobs(buffer^)[i].pPrinterName <> nil then

ListBox1.items.add('pPrinterName='+TarrayofJobs(buffer^)[i].pPrinterName);
             if TarrayofJobs(buffer^)[i].pMachineName <> nil then

ListBox1.items.add('pMachineName='+TarrayofJobs(buffer^)[i].pMachineName);
             if TarrayofJobs(buffer^)[i].pUserName <> nil then

ListBox1.items.add('pUserName='+TarrayofJobs(buffer^)[i].pUserName);
             if TarrayofJobs(buffer^)[i].pDocument <> nil then

ListBox1.items.add('pDocument='+TarrayofJobs(buffer^)[i].pDocument);
             if TarrayofJobs(buffer^)[i].pDatatype <> nil then

ListBox1.items.add('pDatatype='+TarrayofJobs(buffer^)[i].pDatatype);
             if TarrayofJobs(buffer^)[i].pStatus <> nil then

ListBox1.items.add('pStatus='+TarrayofJobs(buffer^)[i].pStatus);
             if TarrayofJobs(buffer^)[i].pStatus <> nil then

ListBox1.items.add('pStatus='+TarrayofJobs(buffer^)[i].pStatus);

ListBox1.items.add('Size='+Inttostr(TarrayofJobs(buffer^)[i].Size));

ListBox1.items.add('Status='+Inttostr(TarrayofJobs(buffer^)[i].Status));

ListBox1.items.add('Priority='+Inttostr(TarrayofJobs(buffer^)[i].Priority));

ListBox1.items.add('Position='+Inttostr(TarrayofJobs(buffer^)[i].Position));

ListBox1.items.add('TotalPages='+Inttostr(TarrayofJobs(buffer^)[i].TotalPages));

ListBox1.items.add('PagesPrinted='+Inttostr(TarrayofJobs(buffer^)[i].PagesPrinted));
             with TArrayofJobs(buffer^)[i].Submitted do
               begin
                 ListBox1.items.add('Submited wYear='+Inttostr(wYear));
                 ListBox1.items.add('Submited wMonth='+Inttostr(wMonth));
                 ListBox1.items.add('Submited wDayOfWeek='+Inttostr(wDayOfWeek));
                 ListBox1.items.add('Submited wDay='+Inttostr(wDay));
                 ListBox1.items.add('Submited wHour='+Inttostr(wHour));
                 ListBox1.items.add('Submited wMinute='+Inttostr(wMinute));
                 ListBox1.items.add('Submited wMinute='+Inttostr(wSecond));
                 ListBox1.items.add('Submited wMilliseconds='+Inttostr(wMilliseconds));
               end;

             ListBox1.items.add(Windir +
format('%-0.5d.SPL',[TArrayofJobs(buffer^)[i].JobId]));
           
ListBox1.items.add('=======================================');
             assignfile(inputfile,Windir +
format('%-0.5d.SPL',[TArrayofJobs(buffer^)[i].JobId]));
             reset(inputfile);
             repeat
               readln(inputfile,line);
               ListBox1.items.add(line);
             until eof(inputfile);
             closefile(inputfile);

ListBox1.items.add('=======================================');

             SetJob(hPrinter, TArrayofJobs(buffer^)[i].JobId, 0, nil,
JOB_CONTROL_CANCEL)
           end;

       end;
     FreeMem(Buffer, pcbNeed);

     WinSpool.ClosePrinter(hPrinter);
   end;
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6261214
In your main forms declaration, after the private keyword, add

 Procedure WMSpoolerstatus( Var msg: TWMSpoolerStatus );
   message WM_SPOOLERSTATUS;
   
This declares a message handler. You implement it like this in the units
Implementation section:

 Procedure TFormX.WMSpoolerstatus( Var msg: TWMSpoolerStatus );
 Begin
   label1.caption:= Format('Spooler status code: %d',
                           [ msg.JobStatus ]);
   label2.caption:= Format('Jobs left: %d', [msg.JobsLeft]);  
 End;
 
You need the Messages unit in your uses clause (should already be
there), this unit is also where you can look up the definition of the
TWMSpoolerStatus record.

0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6261775
Hello?
0
 

Author Comment

by:M_AR
ID: 6262090
Thanx  Epsylon for the code provided.  Actually it didn't fix my problem.  I've found a way to do it and it work.  So no more problem!  I'll give you the points anyway because the comment you gave me helped me to solve another of my problem.  Accessing the data structure of the printer and the print job!
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 13

Expert Comment

by:Epsylon
ID: 6262286
Thanks :o)
0
 
LVL 1

Expert Comment

by:Dumani
ID: 6679997
MAR how did you find the solution? and if this comment didn't why did you accept it? can you email me the solution?

Regards,
ates@anet.net.tr
0
 

Expert Comment

by:moonrise
ID: 6715814
Could you please send me the solution: ymailhot@magma.ca

Thank you.
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6716909
Or can you put here ?
Maybe someone pay the points for an answer .
0
 

Expert Comment

by:monitorwa
ID: 14207519
Did anyone ever find out how he sorted it out? if so I would love to know
dave.r@monitorwa.com.au

thanks

Dave
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This video discusses moving either the default database or any database to a new volume.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now