Environment: Visual C++ 6.0, Windows NT 4.0 / Windows2000
Recently we had to do some printing on our IIS-Server. Printing on a physically existing printer was no problem. But after that we tried to print into files and send the files to the appropriate user.
Printing to “FILE:”-port caused the spooler-service to ask for a destination file, which you had to type in manually. Of course this was not the right approach for our IIS-server.
After studying the MSDN I found “The Print Monitor API” (refer to this for further information) which explains how to implement a print monitor. A print monitor is a DLL that exports some specific functions to enable the print spooler to do customized tasks–for example to print not to a printer but into a directory.
I used the print monitor example from the Microsoft DDK as a template to implement this print monitor. The example in the DDK was very complicated and did more than I wanted it to do (it should just redirect the print jobs into appropriate files).
Notice that the file WINSPLP.H was shipped with the Microsoft Windows NT 4.0 DDK.
The heart of the our monitor is the CPortList class. It…
…stores all ports in the registry.
…loads the ports from the registry at start-up of the spooler-service.
…holds all handles to opened files.
…supplies a list of all known ports to MyEnumPorts.
Refer to source code for detailed information.
It supplies all functions that are exported from the DLL:
Called by the spooler-service to obtain pointers to all the other functions, and to do some init tasks, of course.
Called by the spooler-service to obtain a list of the ports of our print monitor
Called by the spooler-service to open the port
Called by the spooler-service to start the printing of a print job. This will create a new file in the ports output directory and keep a handle to the opened file.
Called by the spooler-service to write to the port. This will write some data to the file. Will be called more than once.
Supplied, but not implemented (no need for)
Called by the spooler-service to write to the port. Called after all the data is written to the file. This will close the file.
Called by the spooler-service to close the port
Called by the spooler service to add a new port. The user has to specify the output directory.
supplied, but not implemented (no need for)
I added this function to give any application the possibility to wait for finishing a print job. This function expects as a parameter the complete path of the file you are waiting for. This function will return when the file has been completely written.
Notice that the path consists of one byte characters, to simplify interaction with Visual Basic.
To install the DLL just…
1. Copy the DLL to the System32-Directory.
2. Add following entries to the registry:
“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlPrintMonitorsLocal Directory Port”
“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlPrintMonitorsLocal Directory PortDriver” = “dirport.dll”
3. Restart your Spooler-Service
Thank you for reading this.
Any comments appreciated.