michalksweda
Flexera beginner

Enumerate printers

Hi I'm InstallShield noob. I'm working on a InstallScript CA where I get the list of printers and their parameters to be inserted to a combobox in basic msi project. I will need to filter out faxes, etc from this list. Also I need the printer port to be available. I have been searching online but I couldn't find a solution. Please help.
Labels (1)
0 Kudos
3 Replies
Jenifer
Flexera Alumni

HI @michalksweda ,

 

There is no direct installscript function to retrieve it,but it can be achieved by implementing Microsoft's function "EnumPrinters" by adding necessary header files to  installscript

The below sample article can help you with how to add Windows API to installscript.

https://community.flexera.com/t5/InstallShield-Knowledge/Displaying-a-File-Browse-Dialog-in-an-Insta...

 

EnumPrinters :https://docs.microsoft.com/en-us/windows/desktop/printdocs/enumprinters

Add Winspool.h  as a header to it.

 

Thanks,

Jenifer

I'm doing something wrong as I get the error:

MSI (c) (8C:08) [16:34:43:534]: Leaked MSIHANDLE (76) of type 790541 for thread 14544
MSI (c) (8C:08) [16:34:43:534]: Note: 1: 2769 2: PopulatePrinterSelectionComboBoxCustomAction 3: 1
Info 2769. Custom Action PopulatePrinterSelectionComboBoxCustomAction did not close 1 MSIHANDLEs.
CustomAction PopulatePrinterSelectionComboBoxCustomAction returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 16:34:43: PopulatePrinterSelectionComboBoxCustomAction. Return value 3.

My code is

// structure for EnumPrintersA from winspool.drv
typedef PRINTER_INFO_5
begin
	LPSTR pPrinterName;
	LPSTR pPortName;
	LONG Attributes;
	LONG DeviceNotSelectedTimeout;
	LONG TransmissionRetryTimeout;
end;
// helper functions used in PopulatePrinterSelectionComboBoxCustomAction located in Windows installation
// winspool.drv EnumPrintersA
prototype INT winspool.EnumPrintersA(LONG, BYREF STRING, LONG, BYREF POINTER, LONG, BYREF LONG, BYREF LONG);

function PopulatePrinterSelectionComboBoxCustomAction(hMSI)
 NUMBER nResult;
 STRING svName;
 STRING svPortName;
 STRING szMsg;
 STRING svPrinterName;
 STRING svTarget;
 NUMBER nvByteCopy;
 NUMBER nvNumberOfDevices;
begin
 svName = "";
 svPortName = "";
 // Load winspool.drv so you can call EnumPrintersA
 nResult = UseDLL("winspool.drv");
 if (nResult < 0 ) then
  return ERROR_FUNCTION_FAILED;
 endif;
 // Windows API call builds list of installed printers
 nResult = EnumPrintersA(2, svName, 5, pPointer, 500, nvByteCopy, nvNumberOfDevices);

At the EnumPrintersA, the function call crashes the installer. What I'm doing wrong?

0 Kudos
Jefferyollsan
Flexera beginner

Running printer inventory has the drawback of being dependent on the systems that are online at the time of the report. It can take a long time to get everyone to report back with accurate printer information at this site if you manage a fleet of distant users with direct attached printers. Either set up a script to run in the background with the hopes of collecting all remote users, or put a script on their system that reports back once a day or something similar.

Life is a gift
0 Kudos