A portable way to identify a printer - physical or virtual

I need direct printer access features for my site, with the ability to distinguish a physical printer from a virtual printer (file).

Coupons.com has this feature through its own binary file, which must be installed by the user. I would rather avoid this.

SmartSource.com does this through a Java applet:

Smart Source Java Applet

Does anyone know how to do this? I dug up these Java APIs a bit and see nothing that would allow you to define a physical virtual, except that I looked at the name (which seems prone to erroneous identification). It would be nice to do this in Java, because I already know how to write Java applets. Otherwise, is there a way to do this in Flash or Silverlight?

Thanks in advance.

EDIT: Well-deserved award for Jason Spiersky, who designed the elegant solution. Thanks to those who shared their ideas, as well as those who really researched SmartSource.com solution (for example, Adrian).

+6
java flash printing silverlight hardware
source share
3 answers

Well, here is what I have found so far (this is not an exhaustive test in any way, but it was a fun problem to try to handle). it seems like there might be some help by looking at how the validatePage () method works in the PrinterJob class. It seems that if the job on the printer is virtual than any attempt to set the page, then ImageableArea will always return a value exactly equal to the default ImageableArea pages, while trying to do the same with a real printer will return slightly lower values ​​(to take into account the edge of the paper are stored in the printer mechanism, which helps in this problem is that if you just ask the printer about it by default, before calling confirmation, you will get an optimistic result, and if you compare this with the confirmed answer om, you can make a simple, if a test. I have written a code for it, which seems to be working with graphics printers and these printers that I have on my desktop (again, it is not exhaustive, but it can act as a starting point)

import java.awt.print.*; import javax.print.PrintService; import javax.print.attribute.Attribute; public class DetectFilePrinter { public static void main(String[] args) { PrinterJob job = PrinterJob.getPrinterJob(); PrintService printer = job.getPrintService(); System.out.println("Printer Name:"+printer.getName()); System.out.println(printer.toString()); PageFormat page = job.defaultPage(); double default_width = page.getWidth(); double default_height = page.getHeight(); Paper paper = new Paper(); paper.setImageableArea(0, 0, Double.MAX_VALUE, Double.MAX_VALUE); page.setPaper(paper); PageFormat fixed_page = job.validatePage(page); double fixed_width = fixed_page.getImageableWidth(); double fixed_height = fixed_page.getImageableHeight(); //So far all of my tested "image printers" return the same //height and width after calling validatePage() if(default_height == fixed_height && default_width == fixed_width) { System.out.println("This looks like a \"image printer\""); } else { System.out.println("This looks like a \"real printer\""); } } } 
+6
source share

As you say, there are ways to gather some information about the printer:

javax.print.attribute.standard.PrinterMakeAndModel looks promising.

File ban: destinations on any printer and printing on any printer with the word PDF in the printer, and the model probably covers 90% of cases, judging by this list of virtual printing software . You are realistically not going to trigger false positives on a PDF word.

If this feature is not perfect, your client is unlikely to notice; your competitors probably also have some kind of terrible kludge, because they know for sure that this feature is more of a "security theater" than actual security.

+1
source share

I know how to do this very easily on Win32. There is a structure called PRINTER_INFO_2 that has a field called pPortName. You can compare it with the string "FILE" and get all the queues that are connected to the port "FILE". And you can likewise add parsing logic to discover other virtual printers. This structure is populated by Windows when GetPrinter is called with a printer descriptor. Now the question is how to do this in .NET. I saw one way that uses sorting. I saw code snippets at http://vbcity.com/forums/t/66183.aspx . You can also look at C # interop using pInvoke. http://pinvoke.net/default.aspx/Structures/PRINTER_INFO_2.html

Hope this helps.

+1
source share

All Articles