MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: Printer[Next]: Printer Installation
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Tips and Tricks->Printer->Printer Driver Installation

Printer Driver Installation

You may also wish to have a look at the "Device Driver Installation" section in this manual.

The following code uses a common macro (see below) to install a printer driver:

;--- Create INSTALLDIR ------------------------------------------------------
<$DirectoryTree Key="INSTALLDIR" Dir="C:\Program Files\<$ProdInfo.ProductName>" CHANGE="\">

;--- Add the driver files (components generated) ----------------------------
<$Files "HPWD*.*"     DestDir="INSTALLDIR" Comment="Compressed Driver files.">
<$Files "hp430ka.inf" DestDir="INSTALLDIR" Comment="Specifies how to install the drivers.">
<$Files "hp430ka.cat" DestDir="INSTALLDIR" Comment="Used by the INF.">

;--- Install the driver -----------------------------------------------------
<$InstallPrinterDriver Inf="hp430ka.inf" Name="HP Deskjet 430 printer" DirKey=^INSTALLDIR^>

The name "HP Deskjet 430 printer" used above must match that used in the ".inf" file so you will need to work this value out.

If you can't work out why the driver install fails then copy and paste the command line from a log file and execute it without the "/q" option.

The "InstallPrinterDriver" macro

The macro shown below is used by the above code, it should be defined once in a convenient header file.

The code does not do any error checking (as this does not appear possible), if you know how this can be added then please let me know (likewise any other improvements).

I am not sure all printer drivers can be handled this way, all I can say is that it has worked for me.

#( ''
   #define InstallPrinterDriver             ;;Version 09.060

   ;--- Some parameter validations ------------------------------------------
   {$!KEYWORDS}                        ;;Don't Expect any keywords!
   {$!:INF,NAME,DIRKEY}                ;;List all supported parameters

   ;--- At least for now only allow use once per MSI ------------------------
   #ifdef  @@Used-InstallPrinterDriver
       #error ^The "InstallPrinterDriver" is currently limited to one user per MSI!^
   #elseif
       #define @@Used-InstallPrinterDriver
   #endif

   ;--- Set up the 2 parameters (CustomActionData) --------------------------
   ;#data "CaData" 2                  ;;Needs PPWIZARD update...
   ;    "INSTALLDIR"   "[{$DirKey=^INSTALLDIR^}]"
   ;    "RUNDLL32.EXE" "[SystemFolder]rundll32.exe"
   ;#data
   #define+ _PrinterDriverDirKey_     {$DirKey=^INSTALLDIR^}
   #define+ @@CludgeName              DriverCaDataCludge
   #include "<$@@ThisMmh>"  "[<$@@CludgeName>]"

   ;--- Deferred Custom Action which accesses 2 passed parameters -----------
   <$VbsCa Binary="InstallDriver.vbs" DATA="CaData">
   #( '<?NewLine>'
       <$VbsCaEntry "InstallDriver">
           ;--- Get passed parameters ---------------------------------------
           CaDebug 1, "Installing driver : {$Name}"     ;;Look in .inf for the correct/required value
           CaDebug 2, "Getting parameters"
           dim INSTALLDIR    : INSTALLDIR = VbsCaCadGet("INSTALLDIR")
           dim RUNDLL32      : RUNDLL32   = VbsCaCadGet("RUNDLL32.EXE")
           dim INSTALLDIR_NS
           INSTALLDIR_NS = INSTALLDIR
           if  right(INSTALLDIR_NS, 1) =  "\" then
               INSTALLDIR_NS = left(INSTALLDIR_NS, len(INSTALLDIR_NS)-1)
           end if

           ;--- Execute the command -----------------------------------------
           dim Cmd : Cmd = """" & RUNDLL32 & """ printui.dll,PrintUIEntry /f """ & INSTALLDIR & "{$Inf}"" /l """ & INSTALLDIR_NS & """ /ia /m ""{$Name}"" /h ""Intel"" /v ""Windows 2000"" /q"
           CaDebug 2, "Executing: " & Cmd
           dim Rc  : Rc = VbsCaRunSync(Cmd, 0, "")
           CaDebug 2, "Completed"
           CaDebug 0, "Note that there appears to be no way to detect failure..."
       <$/VbsCaEntry>
   #)
   <$/VbsCa>

   ;--- Set up the Deferred custom action passing the CustomActionData ------
   <$VbsCaSetup Data="CaData" Binary="InstallDriver.vbs" Entry="InstallDriver" Seq="DuplicateFiles-" CONDITION=^<$CONDITION_EXCEPT_UNINSTALL>^>
#)
#evaluate ^@@ThisMmh^   ^'<?InputComponent>'^
#if    [1 = 0]               ;;Never true (Cludge so it can be used in the macro)
   [DriverCaDataCludge]
   ;--- This section included by #include statement above -------------------
   #data "CaData" 2
      "INSTALLDIR"   "[<$_PrinterDriverDirKey_>]"
      "RUNDLL32.EXE" "[SystemFolder]rundll32.exe"
   #data
   [DriverCaDataCludge]
#endif

Microsoft Bug

Even though you have used the "/q" option to suppress popups (quiet mode) you may be prompted to confirm installation if the drivers don't have a digital signature (depending on Windows options). This may prevent a silent installation of your MSI or you may need to detect and respond to this popup (sendkeys perhaps?).

I have this happen even for a driver which appeared to have a valid digital signature...


Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: Printer[Next]: Printer Installation


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Sunday February 28 2016 at 3:45pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.