1. Christopher Craft
  2. PowerBuilder
  3. Monday, 18 March 2024 18:13 PM UTC

PB 2022 1900

Our application can run as a service to process print jobs.  When this service first starts up it gets a list of valid printers so when the user schedules it we only show them the printers that are setup on that machine.  All this works great until they select a printer that will prompt the user to save the document in some directory.  These printers are 'Microsoft Print to PDF', 'OneNote', etc.  I was hoping I could look at the port setting when getting the list of printers to determine this and then just not show those but the port will show as LPT1 or some other valid entry so I can't use that.

 

Anyway, if someone might have a way to determine these types of printers I would love to know how.

 

Thanks,

Chris Craft

Accepted Answer
Roland Smith Accepted Answer Pending Moderation
  1. Monday, 18 March 2024 21:02 PM UTC
  2. PowerBuilder
  3. # Permalink

I've been working with the EnumPrinters function. I did some investigation and it isn't possible. You'll have to hard code a list of printer names to not show the user.

Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 27 March 2024 01:14 AM UTC
  2. PowerBuilder
  3. # 1

I'm attaching a small, sample PB app named "FindPrinters" that uses WMI that examines the properties of each Windows printer and makes a determination on each one if it is a real/physical printer or a "print-to-file"/non-physical/virtual printer. I've based the logic on hints posted in StackOverflow.com, but admittedly, there may not be any foolproof way to make an accurate determination 100% of the time. I'm quite limited in my ability to test, since I have access to only a single physical printer at home and at work.

I would very appreciative if anyone following this thread would download and test the app. The app optionally supports the display of many of the printer's property values to let you see most of the information WMI is providing. Any feedback you can provide to improve the logic will be valuable.

John

Attachments (1)
Comment
  1. John Fauss
  2. Sunday, 14 April 2024 22:41 PM UTC
Thank you for replying, Mark. The lack of documentation and explanation regarding what goes into these properties and how their values is set is, well, frustrating is best word I have for it. It would appear that the only rule is "there are no rules" when it comes to how a printer driver replies to the Windows O/S. I don't see any reliable way to establish that the "printer" on the other end of a Windows printer definition is hardware or software and that appears to be by design. Chris Craft's proposed solution would appear to be a reasonable one.
  1. Helpful
  1. Mark Goldsmith
  2. Monday, 15 April 2024 00:30 AM UTC
Agreed, thanks John!
  1. Helpful
  1. Christopher Craft
  2. Tuesday, 16 April 2024 22:39 PM UTC
Thanks for that demo John! I tried it out as well and like Mark said - the network printers looked to be the same. Really appreciate you going the extra effort to see if it was possible though!



Chris
  1. Helpful
There are no comments made yet.
Christopher Craft Accepted Answer Pending Moderation
  1. Wednesday, 20 March 2024 22:20 PM UTC
  2. PowerBuilder
  3. # 2

Thanks for all the thoughts.  I had a feeling there was no easy silver bullet.  I will take a look again at the WMI stuff but I think I might just allow them to select which printers they want visible to the end user. Might be a feature anyway - some printers they don't want them to select. 

Thanks again! Always love your responses.

Chris Craft

Comment
There are no comments made yet.
Mark Goldsmith Accepted Answer Pending Moderation
  1. Monday, 18 March 2024 21:22 PM UTC
  2. PowerBuilder
  3. # 3

Hi Chris,

I'm not sure how ironclad this will be but you could look in the registry and see how the key values differ between a physical and logical printer. For example, a logical printer tends to have an empty Location value and the Print Processor tends to be "winprint" (but these could change with future OS updates).

You can find the information in the registry here: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\[printer name]

You may also find something here that might work for you: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Drivers\Version-3

HTH...regards,

Mark

Comment
  1. Mark Goldsmith
  2. Tuesday, 19 March 2024 17:48 PM UTC
Thanks Roland, sounds like locations can't be relied upon. My physical printers all have something like "http://192.168.2.182:80/wsd/pnpx-metadata.cgi" for the location...maybe it's due to how they've been installed (eg they're all network printers versus direct attached). The PrinterDriverData value unfortunately wouldn't work under my configurations as only some have a ".dll" as part of the entry...really tricky to find consistency here and may take looking at more than one value to determine physical versus logical.



Looking at the Manufacturer value under the second registry path I provided (as well as HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Drivers\Version-4) one could safely eliminate the "Microsoft" ones since I'm pretty sure they don't make printers, as well as the ones that have an empty value (eg PDFCreator)...but that logic would certainly need to be tested for accuracy and consistency.
  1. Helpful
  1. John Fauss
  2. Tuesday, 19 March 2024 20:27 PM UTC
One purpose of a "Save As" printer driver (or whatever you want to refer to it as) is to mimic the (input) functionality of a Windows-driven printer driver. In order to accomplish that successfully, the "Save As" printer driver has to satisfy the look and feel of a hardware printer's printer driver. Therefore, it does not surprise me that there does not appear to be any way to tell via the normal software interfaces (API functions, registry, etc.) that there is or is not an actual printer involved.

This is why I suggested looking at the information in WMI, as the information it can supply seems closer to the interface between software and hardware.

I can't say with any certainty that it's a viable solution, but I think it is worth looking into and it is reasonably easy to do.
  1. Helpful 1
  1. Mark Goldsmith
  2. Tuesday, 19 March 2024 21:30 PM UTC
Hi John...yes, based upon your suggestion I had a look through the values via WMIC commands and then again via the wbemtest app. I may have missed something but unfortunately there wasn't anything obvious that might be useful to determine whether a printer is logical or physical.

While there is some overlap in data points between the win32_printer class and the registry, there are some entries in the registry, such as the Manufacturer value that I referred to in my OP, that are not included in the win32_printers class.

Maybe using a combination of the PrintProcessor and Manufacturer values from the registry are possibilities to test against.
  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Monday, 18 March 2024 19:51 PM UTC
  2. PowerBuilder
  3. # 4

Hi, Chris -

Interesting question!

I think WMI (Windows Management Instrumentation) may be an easy way to determine this. A post on StackOverflow states that the "Published" property of the Win32_Printer WMI class will report TRUE if the printer is a real printer and FALSE otherwise:

    https://stackoverflow.com/questions/18826447/how-to-determine-if-printer-is-xps-c-sharp

This appears to be the case, but my ability to test this hypothesis is quite limited.

A while back I published in CodeXchange an example app that shows how you can query WMI classes/properties:

    https://community.appeon.com/index.php/codeexchange/powerbuilder/281-wmi-windows-management-instrumentation-class-properties-inspector#338

The original sample application is a general-purpose WMI class/properties inspector. Later, I added a second, smaller app that issues a specialized query for info regarding network adapters. This second app will be of more interest to you, as it can be easily adapted to return instead the "Name" and "Published" properties for all instances of the Win32_Printer class for the all of the printers available to the user.

HTH

Best regards, John

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.