Solved

print spooler job access!

Posted on 2001-07-04
10
1,005 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
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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
 
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

821 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