Printing Pipeline

Discussions related to SoftPro Select user interface development.

Moderator: Phil Barton

roteague
Posts: 292
Joined: Thu Sep 25, 2008 4:49 pm
Location: Honolulu, Hawaii

Printing Pipeline

Post by roteague »

I'm beginning to do some work on the printing pipeline, and I need more information on how to interact with this. The SDK documentation is a bit sparse on this subject.

Specifically,

1.) What happens in each stage of the pipeline? Essentially, I need to grab the order being printed and copy information about the document to another system. I don't know which stage it would be in. I assume, Processing, but I don't know for sure.

2.) How do I go about making the SoftPro program aware of the object that I've created to make sure it gets called in the correct place?

3.) Do you have any samples we could look at? C# would be fine and would give us a place to start.

Thanks for all your help,

Robert
Robert
Mark McKenna

Re: Printing Pipeline

Post by Mark McKenna »

Hi Robert,

Both the stage and priority level assigned to each dispatch handler combine to determine the order in which they execute. The only real "requirement" is that all Pre-Processing stage handlers finish executing before any Processing stage handlers may start, and all Processing stage handlers must finish before any Post-Processing handlers may start. In general, the Processing stage is where the handlers execute that provide the output service being requested. Its where the "rubber meets the road", if you will. For example, a "print to printer" handler may execute here, as well as a "deliver fax" or "send email" handler. The Pre-Processing stage, then, is typically reserved for any prep work necessary to transform the output into a form that it is ready to be printed or faxed or emailed. For example, this is where a collation handler might execute that rearranges the output into the proper sequence. The Post-Processing stage is where follow up handlers would run, such as those that perform auditing functions.

1. This sounds like an auditing function that would execute during the Post-Processing stage. That way, the appropriate Processing handler can attempt to output the information to whatever device (loosely) is specified, and if the pipeline reaches your handler that you've plugged in to the Post-Processing stage, you'll know that the output proceeded normally and may be audited. We're working out the details as to how we best expose the information about the Order from which the print job originated, but it is likely that we will utilize the IOrder interface. That decision and update will be part of the SP2 release to your installed version that is expected to be available by the end of October. For now, you can stub in an Order Number (or ID or whatever it is you need) and then safely assume that SP2 will provide you that detail.

2, 3. When you create your own custom package and register it, you may optionally register one or more dispatch handlers at that time. You'd do so using the ProvidePrintDispatchHandler attribute on your package class itself, and then registering it inside the package's override of OnInitialize, like in the example below. Note that this is not a complete example of how to create the packages themselves - you can use the Visual Studio project template provided with the SDK to quickly create a ready-to-run custom package, and then customize it similar to the example below for your pipeline handling needs.

Code: Select all

namespace MyNamespace
{
  // this configures the MyDispatchHandler handler to execute within the Post-Processing stage and with Priority 5 
  [ProvidePrintDispatchHandler(typeof(MyDispatchHandler), PipelineStage.Postprocessing, 5)]
  public class MyPackage : SoftPro.Select.Shell.Package
  {
    protected override void OnInitialize()
    {
      base.RegisterPrintDispatchHandler(new MyDispatchHandler());
    }
  }
}
By default, we only provide one Post-Processing dispatch handler (auditing) and it has a priority level of 10. By assigning 5 to your handler, you would execute first, and then you could either have your dispatch handler's override of OnHandleDispatched return true to halt the pipeline after you've performed your own auditing, or return false to allow our auditing handler to proceed as well.
JDavis
Posts: 97
Joined: Mon Sep 22, 2008 5:10 pm

Re: Printing Pipeline

Post by JDavis »

Mark, thanks for the information. We forgot to ask, how do we get access to the actual print job and then copy that file to another location? Also, can you do this before and after the conversion to PDF?
Mark McKenna

Re: Printing Pipeline

Post by Mark McKenna »

The dispatch handler that you register via your custom package must implement the SoftPro.Select.Shell.Printing.IPrintDispatchHandler interface. We also provide an abstract base class that you can simply derive from called PrintDispatchHandler in that same namespace. The IPrintDispatchHandler contract requires that you provide an implementation of OnHandleDispatched which takes a single IPrintJob parameter. This provides your access point into the currently executing print job, and includes an enumerable Items collection of type IPrintJobItem. Each IPrintJobItem object represents a single entry in the print job and allows you to locate the related PDF's FileInfo object.

By the time it is dropped onto the printing pipeline, the print job item will always be in PDF format when it is sourced by ReadyDoc or Report. Note that by default, there is a dispatch handler running in the Pre-Processing stage that provides collation services, so it is possible that the PDFs you are trying to interact with via IPrintJob.Items during the Processing stage have undergone some initial transformations and no longer represent a 1:1 correlation with the original selection of, say, ReadyDocs.

This is the general idea:

Code: Select all

protected override bool OnHandleDispatched( IPrintJob job )
{
    foreach ( IPrintJobItem item in job.Items )
    {
        // locate the PDF
        FileInfo fileinfo = item.Properties["FileLocation"] as FileInfo;
        if ( fileinfo != null )
        {
             // copy the file
        }
    }
    return false; // allow the pipeline to continue
}
roteague
Posts: 292
Joined: Thu Sep 25, 2008 4:49 pm
Location: Honolulu, Hawaii

Re: Printing Pipeline

Post by roteague »

Mark McKenna wrote:By the time it is dropped onto the printing pipeline, the print job item will always be in PDF format when it is sourced by ReadyDoc or Report.
Which version of PDF is targeted by the product? Many of our people here use a very old version, and I'd like to validate we won't run into any issues.
Robert
Mark McKenna

Re: Printing Pipeline

Post by Mark McKenna »

The PDF files that travel along the printing pipeline should currently conform to, at minimum, Version 1.4 of the Adobe Portable Document Format specification. I believe Adobe Acrobat 5.0 (2001) was the first version to support this specification. Further, depending on the features we activate for a particular source document, there is a good chance that the generated file would also conform to the earlier 1.3 specification which correlates to Adobe Acrobat 4.0 (1999).
roteague
Posts: 292
Joined: Thu Sep 25, 2008 4:49 pm
Location: Honolulu, Hawaii

Re: Printing Pipeline

Post by roteague »

Mark,

Thanks for all your help so far.

I created a package with the Package Template Wizard. When compiling it I get the following output:

Code: Select all

Compile complete -- 0 errors, 0 warnings
DMSTestPrintDispatchHandler -> C:\Documents and Settings\rmtxxxx\My Documents\Visual Studio 2008\Projects\Test Projects\DMSTestPrintDispatchHandler\DMSTestPrintDispatchHandler\bin\Release\DMSTestPrintDispatchHandler.dll

      copy DMSTestPrintDispatchHandler.dll "C:\Program Files\SoftPro\Select 2.2\"
      "C:\Program Files\SoftPro\Select 2.2\spregpkg.exe" /r /p:DMSTestPrintDispatchHandler.dll /rootsuffix:Exp
      "C:\Program Files\SoftPro\Select 2.2\Select.exe" /setup /rootsuffix:Exp
    
        1 file(s) copied.
Parsing command line arguments...
Loading assembly...
Successfully loaded assembly
Registering package...
Successfully registered package
So, it looks like the the DLL was copied to the correct directory and registered correctly. However, the OnInitialize method never gets called (the print option is also greyed out, so perhaps that has something to do with it).

The base class is defined as:

Code: Select all

namespace DMSTestPrintDispatchHandler
{
    [RegisterPackage("My Company", "DMSTestPrintDispatchHandlerPackage", "1.0.0.0", "")]
    [RegisterProduct("My Company", "DMSTestPrintDispatchHandlerPackage", "1.0", "Test Package for Printing Pipeline.", "")]
    [Guid(MyPackage.PackageGuidString)]
    [ProvidePrintDispatchHandler(typeof(DMSTestPrintDispatchHandler), PipelineStage.Postprocessing, 5)]     
    partial class DMSTestPrintDispatchHandlerPackage : Package
    {
        protected override void OnInitialize()
        {
            //TODO: Provide package initialization logic here.
            base.RegisterPrintDispatchHandler(new DMSTestPrintDispatchHandler());
        }
    }
}
The DMSTestPrintDispatchHandler is based upon your code above.

First, am I missing something in my class description and secondly, when does this module actually get loaded by SoftPro?

Thanks for all your help,
Robert
Mark McKenna

Re: Printing Pipeline

Post by Mark McKenna »

When you ran Select to test your work, did you target the Exp rootsuffix?

Code: Select all

Select.exe /rootsuffix:Exp
The library you compiled was registered to that experimental rootsuffix, which acts as a sort of developer sandbox. If the package is registered under a different rootsuffix than the one Select is being run under, then there will be package loading problems. But let's first answer the initial question before digging deeper.

Regarding module loading, the system won't load the package until it is first required. In your case, the first time you attempt to print (email, etc.) is probably the point at which your package will load because the pipeline dispatcher will gather up all the registered handlers, and each handler knows its owning package, so the package will be loaded (JIT) in order to instantiate your handler. Of course, if you extend your package to provide additional functionality, it may end up being loaded earlier as it is first needed by Select.
roteague
Posts: 292
Joined: Thu Sep 25, 2008 4:49 pm
Location: Honolulu, Hawaii

Re: Printing Pipeline

Post by roteague »

Thanks Mark. The program is being run under the experimental rootsuffix where it is being registered. I'm not as familiar with the front end of the program as I need to be, so I'll have to find out why the Print command isn't enabled, before I can test the package. Thanks for your help.
Robert
Mark McKenna

Re: Printing Pipeline

Post by Mark McKenna »

On the Documents tab within an order, be sure that you have selected a ReadyDoc from the tree on the left and "pushed" it into the "Selected ReadyDocs" list on the right. The print options are all disabled unless there is something in the Selected (working) list. If that fixes your problem, then once you click Print you should see your package initialize because the registered dispatch handler will essentially call for it.
Post Reply