A long while back I posted an entry regarding how to install a printer driver programmatically by shelling out and using rundll32.exe to execute the PrintUi.dll which can handle a variety of print tasks including installing a printer driver. This code's been working fine, but it's been giving me some problems under Vista for a couple of reasons.
The firsts issue is that I use the driver to install a PostScript driver so I can print a PostScript file to disk which later can be converted by GhostScript. To do this I've been using one of the default installed printer drivers for Windows which has been:
Apple Color LW 12/660 PS
Unfortunately this driver no longer exists in the default printer list in Vista. In fact, Microsoft ditched all the Apple printers - well they are a bit uhm dated. <s> So the next step was to find a driver that exists under WinXp, Win2003 and Vista (don't have older versions around to check but it might work under Win2k as well). The driver I ended up picking was:
Xerox Phaser 1235 PS
But even after switching to the new and available printer I continued to get error message from the driver installation routine. The main reason is that I previously had used the /v[ersion] switch with "Windows 2000 and XP" which works fine for all OS's through XP. On Vista however, only "Windows XP" works explicitly (there's no Windows Vista switch as far as I can tell).
In the end the following two command lines will install the printer driver:
C:\Windows\system32\rundll32.exe printui.dll,PrintUIEntry /ia /m "Xerox Phaser 1235 PS" /h "Intel" /v "Windows XP" /f "C:\Windows\inf\ntprint.inf" /u
C:\Windows\system32\rundll32.exe printui.dll,PrintUIEntry /if /b "Xerox Phaser 1235 PS" /f "C:\Windows\inf\ntprint.inf" /r "lpt1:" /m "Xerox Phaser 1235 PS"
I'm using this code as part of a setup routine that runs inside of West Wind Web Connection (a FoxPro application) application and here's the complete logic to do the driver installation:
************************************************************************
* InstallPrinterDriver
*********************************************
*** Function: Installs a Windows Printer driver from the stock
*** Windows driver library
*** Assume:
*** Pass:
*** Return:
************************************************************************
FUNCTION InstallPrinterDriver(lcDriverName,lcPrinterName)
LOCAL lcOs, llResult
IF EMPTY(lcDriverName)
*** This color PS driver exists under Win2003, Vista and XP
lcDriverName = "Xerox Phaser 1235 PS"
* lcDriverName = "Apple Color LW 12/660 PS"
ENDIF
IF EMPTY(lcPrinterName)
lcPrinterName = lcDriverName
ENDIF
LOCAL ARRAY laPrinters[1]
lnCount = APRINTERS(laPrinters)
FOR lnX = 1 TO lnCount
IF LOWER(lcPrinterName) == LOWER(laPrinters[lnX,1])
RETURN .t.
ENDIF
ENDFOR
lcOS = "Windows 2000 or XP"
IF OS(3) = "6" && Vista requires XP setting
lcOS = "Windows XP"
ENDIF
loAPI = CREATEOBJECT("wwAPI")
lcExe = loAPI.GetSystemDir() + "rundll32.exe"
lcCmdLine = [printui.dll,PrintUIEntry /ia /m "] + lcDriverName + [" /h "Intel" /v "] + lcOS + [" /f "] + loAPI.GetSystemDir(.t.)+ [inf\ntprint.inf" /u"]
llResult = CreateProcess(lcExe,lcCmdLine,2,.t.)
IF !llResult
RETURN .F.
ENDIF
lcCmdLine = [printui.dll,PrintUIEntry /if /b "] + lcPrinterName + [" /f "] + loAPI.GetSystemDir(.T.) + [inf\ntprint.inf" /r "lpt1:" /m "] + lcDriverName + ["]
llResult = CreateProcess(lcExe,lcCmdLine,2,.t.)
IF !llResult
RETURN .F.
ENDIF
RETURN .T.
This code should adapt reasonably well to anything that can shell out…
The documentation for printui.dll can be found here:
http://www.microsoft.com/windowsserver2003/techinfo/overview/printuidll.mspx
It's not exactly exhaustive - there's no explanation of any of the switches or which combinations are valid - but if you need to set additional flags it's good place to start experimenting.
Other Posts you might also like