I'm trying to build a virtual printer.
There are already some answers like this and this.
However my demand is more specific. I just want to create a virtual printer that can be added into the system and can be accessed from any application. On clicking print command, a dialog looks like a real printer pops out and generates a PDF on printing. Then some more actions, like pushing the PDF to my server, are performed.
Do I need to dig into Windows Driver Kit? Or is there any free SDK for this?
Thanks.
Not sure if this question is still relevant to you, but you'd probably want to think about something like this:
Use the WDK (Windows Driver Kit) to create a Unidrv UI plugin. This will allow you to specify UI during the print (for your printer dialogue). The reason why you'd want to show UI here is because it's one of the only printer driver components that runs in the user session (the same process as the printing application). The XPS pipeline and port monitor are both session 0.
If you want to stick to MS convention, you'll do the spool file to PDF conversion in the render filter of the XPS Filter pipeline (this is if you're using an XPSDrv driver). The filter pipeline is where you have the opportunity to modify the XPS spool data coming in and in the final filter, convert it to your output document type (PDF in your case).
To do post print processing, you might want to consider creating a port monitor (again with the WDK) and kicking off a new process to do the post print processing after the port monitor writes out the print output to disk.
Only problem with this approach is that you can't use port monitors in Version 4 drivers (this is the new type of driver in Windows 8). Version 3 drivers still work in Win 8, but I guess they'll be phased out eventually.
Sorry it's probably not very obvious, but as I say, it's a high level overview (and unfortunately driver development is still very complex beyond a simple print to file). Version 4 printer drivers are becoming a lot easier to develop, but unfortunately with the removal of port monitor support and other improvements, it makes it a lot harder to develop anything requiring post processing.
[DISCLAIMER: I'm associated with the Mako SDK R&D team]
I know you asked for a free SDK, unfortunately I don't know of anything that would be suitable, but I know our company offer a Virtual Printer Platform (SDK) which would be good for you (prints to PDF and supports post print processing). You can find more information at the Mako SDK website
Hope this helps a bit anyway. I know printer driver development can be very confusing at times!
After reading up and doing a lot of research, with the aim to setup up something like redmon and use the printer SDK, I have completed the project using this SDK: http://www.novapdf.com/pdf-sdk.html
This solution however will work with windows only.
[I am not affiliated with novaPDF]
I have investigated an OSX version, however this will be a different build, you can probably set something up using this method: http://www.jms1.net/osx-pdf-services.shtml [I have not yet tried this]
Related
I have used PJL commands with some HP printers to set printer control panel display message and duplexing of PDF documents. I have some customers with similar requirements using Okidata MB760 and MB492 machines. I know the Okidata machines support PJL, but it appears to be a different set of codes from HP (as is the case with every manufacturer - no standard for PJL except the entry/exit codes). Okidata support was unable to provide a programmer's manual or a PJL reference. Does anyone have information specific to these machines or (since each manufacturer tends to use the same codes with slight variations for a long time) for any other Okidata MB machines?
No response, not even comments. I did some testing via "print to file" in Windows and it looks like I can extract enough PJL from there to do what I need to do. But I still hold some small bit of hope that someone - maybe a helpful insider at Okidata? - will post some sort of PJL reference.
You can download a program called PCL Paraphernalia which allows you to connect and execute some PJL commands.
It's not the sleekest of interfaces but the Status Readback Utility option should allow you to retrieve all the allowed variables from the printer
My Bixolon SRP-350II is not shown in the list of available devices given by
posExplorer.GetDevices();
All I see are Microsoft's simulated devices. The printer itself works, I can print on it and, using raw printing, send commands such as "cut". I've installed the OPOS driver for the printer, but nothing changed.
Is it necessary to do some further configuration? Is the order of installing POS.NET, the OPOS-driver and the Windows driver important?
Alright, figured out the Printer had to be configured with PSPLauncher.exe and now it shows up. Still, I am not sure I understand where exactly the benefit of POS .NET lies. I want the customers to plug-in new printers and when using Raw Printing and EscPos-commands, this seems to be much easier.
Plug printer in, install windows driver, set to main printer and then cut-commands etc. are being send in the raw stream.
I can't say directly for printers, but where we get the benefits out of POS.NET is the standard code we wrote for the scanners, or MSRs or cash drawers. All we have to do is install the driver, and configure the device in OPOS configuration (which is probably the step you were missing and resolved with the "PSPLauncher.exe") and we know that it's code-compatible and just works.
We have hundreds of terminals across the country (Australia) and they all use a variety of models and brands for the devices (within a range of tolerance) but because of POS.NET they're all supported.
I've developed a web service for printing (C# MVC 4) that creates XPS documents and then prints them via various printer servers (MS) to various print queues. This all works fine against Sharp print queues, but all font data is lost when printing to Lexmarks although the font sizes remain correct. The XPS documents all present correctly when viewed in an XPS viewer, and when printed out via the viewer to the Lexmarks via the print server work properly. The fonts are on the print servers, the Sharp queues are on the same print servers as the Lexmarks and the fonts are all specified in the XPS documents. Changing the Lexmark printer settings, drivers etc appears to make no difference.
The only pertinent question (from a year ago) on here, said the MS solution was to turn off the print spooler when doing server side printing due to a font conversion bug.
I know this is a pretty vague question, but if anyone has been through this pain and has any tips on how to resolve this I'd appreciate it.
Well, there's not much to go on, but I suspect three things:
The XPS document you are producing references fonts without embedding them
The Lexmark print drivers on your server are XPS drivers
The fonts are not installed on the printers themselves.
Assuming I'm right, changing any of these three facts should rectify the situation, though I make no guarantees about #3.
The reason this is happening is that the fonts are not used until the XPS is rasterized - that is converted into raw image data. I suspect that in the Lexmark case, this is occurring on the device, while in the Sharp case, it is occurring on the print server. This is supported by the fact that printing the XPS document from the XPS viewer works correctly, since this causes the rasterization to occur on the machine where the viewer is running.
Using a non-XPS driver on the print server will cause a bit of a performance hit. The print server will effectively be converting XPS to GDI, which the non-XPS driver will then convert to another PDL, such as PostScript or PCL. I suspect that this is the case with the Sharp drivers, though it may also be that the Sharp driver is an XPS driver that performs the rasterization on the host.
OK..after a lot of testing the following was noted (and may be of help to others).
In answer to the above questions..
1) embedded fonts confirmed and used MS official test XPS files.This did not help.
2) Lexmark driver used was winprint > RAW. changing this didn't help.
2) Fonts are installed on the printer
Tests
1) new print server, printing directly to a sharp printer. Problem appeared in that fonts were lost. The resolution to this was to change the spooler settings to print only after all documents were printed. The problem vanished, however I didn't want to rely on people configuring printers which requires specialist settings, so I rejected that. This is a client's network and I have no control over it.
2)printed to existing web service (using user impersonation) on print server to Sharp queues to confirm that this still worked. Confirmed.
3)Printed to existing web service (using user impersonation) on the print server to Lexmark queues and this still failed and the fonts were lost.
4) Printed from 2 separate IIS boxes to the print server to the Lexmark queues (using a domain app pool identity account) and this now worked correctly (in c# new printserver(\printerservername)) in that the Lexmarks printed correctly.
5)Printed to existing web service (using the domain app pool identity account) on print server to the Lexmark queues and this still failed (in c# new localprintserver()).
6)Printed to existing web service (using the domain app pool identity account) on print server to the Lexmark queues and this still failed (in c# new printserver(\printerservername))
The upshot of all this is that if you print locally the fonts are lost for some odd reason, but if you print remotely, the fonts are retained. All the servers have the same basic set up (no xps viewer etc and the domain app pool account is a service account) and the only difference I can see is the new localprintserver against new printserver(\printservername) calls. The same code was ported from machine to machine with the web config file holding the local or remote setting. All machines have IIS 7.5 .net 4.5 MVC 4 and are in the trusted zone.
So my solution will be split, non Sharp printing will be carried out on the document builder remote to the print server service and Sharp printing will be done on the print server (this is required for the Equitrac "follow me" printing) because I didn't want to use kerberos delegation. As stated it's not my domain and I could see the whole place grinding to a halt print wise over a lost spn or a kerberos failure.
Anyway, hope this helps someone.
can you please help me with the following questions...
If I need a virtual printer that will convert a PostScript stream to a different format, do I have to implement a virtual printer from scratch or implement a rendering plug-in?
The rendering plug-in seems to support only certain customizations. Also the data invariably goes to the spooler which is not needed in this case.
If I implement a virtual printer driver does it completely replace the Microsoft PostScript Driver or the Microsoft Universal Driver?
Since my driver is virtual, does it matter if I write a PostScript compliant or a Universal Driver compliant one?
Any other method to convert a printed document to a custom document format apart from implementing a virtual printer driver? Can I hook on as a port monitor or something? From what I could understand I guess not.
What you need is a port monitor. You can create a virtual printer using the Microsoft Postscript driver found in the WDK. You don't need to provide any code for this part, just an INF and PPD file to describe your virtual printer. Once you have that working and installed, users will then see your virtual printer when they print from an app. This printer will produce a stream of Postscript like any standard Postscript printer, which will then be sent to the printer's port monitor.
Now add a port monitor to handle converting the Postscript stream to whatever format you need. Port monitors are considerably easier to deal with than print drivers.
EDIT: Andy points out in the comments that v4 (ie, Win8) print drivers don't support custom port monitors. However, v3 drivers will still work in Win8.
I know this is old, but these answers would have helped me a couple months ago, when I started this project. I spent a lot of time creating a port monitor, only to find a much easier method in the end (see WritePrinter link below).
If I need a virtual printer that will convert a PostScript stream to a
different format, do I have to implement a virtual printer from
scratch or implement a rendering plug-in?
Rendering plug-in is what you want.
The rendering plug-in seems to support only certain customizations.
Correct -- you'll have to decide if it is enough for you.
Also the data invariably goes to the spooler which is not needed in
this case.
This should not be an issue.
If I implement a virtual printer driver does it completely replace the
Microsoft PostScript Driver or the Microsoft Universal Driver?
If you implement a rendering plug-in, it does not replace the PS/Uni drivers. The PS/Uni drivers are in fact used by a huge number (maybe 90%?) of all "printer drivers". OEMs that make printers don't want to write their own drivers, so they use the PS/Uni driver design -- some create UI plug-ins, some rendering plug-ins, some both, some neither.
Since my driver is virtual, does it matter if I write a PostScript
compliant or a Universal Driver compliant one?
It depends what format you want the data in. If you want bitmap format, a Uni driver is better, if you want PostScript format, PS is better. If you want data for each line drawn, text out, and other GDI operations, then either is fine.
Any other method to convert a printed document to a custom document
format apart from implementing a virtual printer driver? Can I hook on
as a port monitor or something? From what I could understand I guess
not.
Most people that want raw access to the PostScript data, usually to use GhostScript to convert to PDF or other format, use a port monitor to do this. For example, the Virtual PDF Printer that Adobe ships with the full version of Acrobat (Writer), uses a port monitor, and also a rendering plug-in and a UI plug-in, for the PSCRIPT5 driver.
The problem with a port monitor is that it doesn't run in the context of the user -- not in the context of the application/process doing the printing. It runs in the context of the print spooler, and requires a lot of hacks to figure out which user/session is doing the printing.
If you want bitmap data, to save as a JPG/BMP/PNG, for example, then just create a rendering plug-in for the universal printer driver and access/save the bitmap data inside IPrintOemUni::FilterGraphics.
If you want PostScript data, to use with GhostScript (or other library, or your own code) to convert to PDF or other formats, then just create a rendering plug-in for the PSCRIPT5 driver and access/save the PS data inside IPrintOemUni2::WritePrinter.
In either case, you want a rendering plug-in. If you want to easily display a UI while printing, and want your code to run in the same context as the user, and not the spooler service, then make sure you set your printer to print directly to printer -- bypass the spooler. If you use AddPrinter to install your printer, you would use the PRINTER_ATTRIBUTE_DIRECT flag.
Not sure I fully understand. You have an app that produces Postscript and you want to convert that to something else? If the application outputs the 'print ready' data then a new printer driver isn't going to help as the 'queue/driver' is just a way to get the data to the printer and not something that is creating the output file.
You might be best to look at something like: Redmon
This can take the output and spawn an new process. The idea would be that you have it output the Postscript to a file and then you launch some console .exe that you create against it.
Just a thought.
Again not sure which way round you are doing this, but ghostscript is the simplest way to convert a PS output into any other format. It's also pretty easy to write your own output format for ghostscript.
This all happens at the app level - no need to write a driver.
I need to run an equipment audit and to do that I need to obtain the Windows PC, monitor etc. serial numbers.
So I faced with going to each PC and manually writing down the numbers.
Is there a way I can get this programmatically so each user can run a small program and email me the results?
If this information is anywhere, it'd be in WMI (http://en.wikipedia.org/wiki/Windows_Management_Instrumentation) - you could write a VBscript script to query this information and save it to a remote share on a server for example.
Generally no. If your computers are all Dell, though, you might be able to get some information (maybe the serial number?) for the PC itself.
The monitor, if it supports VESA EDID (DDC, EDID, EEDID), may also include a 32 bit serial number - which may or may not have any relation to the serial number printed on the monitor's label. You may be able to access this through the display driver - Windows has access to portions of it (to display monitor resolution and timing) so I expect the manufacturer/model/serial number is stashed somewhere as well.
However, making such a program that would work across all systems and monitors would likely be much more work than simply going to each station and recording it, unless all the systems have the same hardware.
Good luck!
-Adam
I am not quite sure if this is exactly what you want, but there is pay software made by DameWare that allows you to easily remote connect to other machines and get lots of information. I haven't used it much yet, but I think there is a way to make batch scripts so it can go pull information like that for you, or see what apps are installed on the machines. Even worse case though, you don't have to run to each machine. (I am assuming you mean SN like the MS product ID)
WMI is definitely the way to go. You can get quite a bit of useful audit information through that API.
Michael Baird appears to have written a VBS script to read the EDID information. The script reads and parses the monitor EDID information from the registry in order to retrieve asset information.
http://cwashington.netreach.net/depo/view.asp?Index=980&ScriptType=vbscript