Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

print spooler job access!

Posted on 2001-07-04
10
Medium Priority
?
1,012 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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 225 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses

722 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