;;=====================================================================================----- 
;;FUNCTION       AddPrinter()  
;;  
;;AUTHOR         Glenn Barnas 
;;               Based on version 1.2.0 by Allen Powell 
;;  
;;VERSION       2.0.0 - 2009/11/03 
;; 
;;HISTORY        1.0.0 - 2003/05/07 - Initial Release 
;;               1.1.0 - 2006/11/17 - Support for Novarsinstrings, All Vars Dimmed, 
;;                                    Cleaned up code  
;;               1.1.1 - 2006/12/16 - Fixed Code when adding network printers  
;;               1.2.0 - 2007/01/26 - Added Support for LPR Printers 
;;               2.0.0 - 2009/11/03 - Rewrite, GBarnas, for ITCG coding standards, 
;;                                    Vista/Win7 verification, new options for 
;;                                    PortName & Share 
;;  
;;ACTION         Add IP,LPT, or COM Printers locally or remotely. Also, add PrintServer 
;;               connections locally. 
;;  
;;SYNTAX         AddPrinter(Port, PrinterType [, DriverInf] [, PrinterName] [, remotepc] [, Default] [, PortName] [, Share]) 
;;  
;;PARAMETERS     Port - REQUIRED    
;;               - IPAddress(RAW)   (xxx.xxx.xxx.xxx)  
;;               - IPAddress(LPR)   (xxx.xxx.xxx.xxx:LPRQueueName) 
;;               - LPT              (LPT1:)  
;;               - COM              (COM1:)  
;;               - PrintServer      (\\server\printer)  
;;               PrinterType - REQUIRED 
;;               - Descriptor of Printer within INF file  
;;               - Note:  If using a PrintServer, $PrinterType value is ignored.  
;;               DriverInf - OPTIONAL 
;;               - Location and name of INF file containing print drivers  
;;               - Note:  If omitted, attempts to use default Windows Print Drivers  
;;               PrinterDesc - OPTIONAL 
;;               - Description of Printer  
;;               - Note:  If ommitted, $PrinterDesc = PrinterType  
;;               RemotePC - OPTIONAL 
;;               - PC to install Printer/Drivers on.  If omitted defaults to localpc.  
;;               - Note:  Ignored if $Port is a PrintServer  
;;               Default - OPTIONAL 
;;               - 0 = Do not Set as Default Printer (Default)  
;;               - 1 = Set as Default Printer 
;;               PortName - OPTIONAL - name of IP port 
;;	         -default is "IP_<ip address>", ignored unless Port contains an IP address 
;;               Share - OPTIONAL - Share flag 
;;               -0 = Do not share this Printer (Default)  
;;               -1 = Share this printer (uses PrinterName as ShareName) 
;;                        
;;RETURNS        Integer - Status (1=Success/0=Fail) 
;;               1 - Successful  
;;               0 - Failed  
;;               If Failed check @error or see below for custom errors  
;;               -5 - Could not stop print spooler 
;;               -4 - Error connecting to RemotePC  
;;               -3 - Could not open/find INF file  
;;               -2 - Could not find $PrinterType in INF file    
;;               -1 - Unrecognized Port  
;;  
;;DEPENDENCIES   W2K and above, rundll32.dll, printui.dll,PrintUIEntry  
;; 
;;TESTED WITH    W2K3, W2K8, W2K12 
;; 
;;EXAMPLES     
;;               $=AddPrinter("192.168.1.1","Xerox DocumentCenter 555 PCL6","\\Server\PrinterDrives\Xerox\dc555pcl\dc555x.inf","Xerox Document Centre 55  5 PCL6 in Office",REMOTEPC,1)  
;;               $=Addprinter("LPT1","HP LaserJet 8100 Series PS",,"HP8100 in IS(test)")  
;;               $=AddPrinter("192.168.1.1","HP LaserJet 8100 Series PS",,"HP8100 in IS(test)",,1)  
;;               $=AddPrinter('\\server\printer','_')  
; 
Function AddPrinter($Port, $PrinterType, OPTIONAL $DriverInf, OPTIONAL $PrinterName, OPTIONAL $Target, OPTIONAL $Default, OPTIONAL $PortName, OPTIONAL $Share)
 
  Dim $							; Temp var 
  Dim $Found						; flag - item exists in INF file 
  Dim $IPPrinterKey					; reg key 
  Dim $PrinterCMD					;  
  Dim $Fh						; File Handle 
  Dim $Spooler						;  
  Dim $Services						;  
  Dim $Line						; line to read 
  Dim $objService					;  
  Dim $PrintServer					;  
  Dim $LPRQueue						;  
  Dim $AutoShare					; Auto-share the printer? 
 
  $AddPrinter = 0					; assume failure 
 
  ; use default INF file if none specified 
  If $Driverinf = ''
    $DriverInf = '%windir%\inf\ntprint.inf'
  EndIf
 
  ; make sure it exists 
  If Not Exist($DriverInf)
    Exit -3
  EndIf
 
  $PortName    = IIf($PortName, $PortName, 'IP_' + $Port)
  $PrinterName = IIf($PrinterName, $PrinterName, $PrinterType)
  $AutoShare   = IIf($Share, ' /Z', ' /z')
 
  ; Make a copy to work with 
  Copy $driverinf '%temp%\addprinter.txt'
 
  ; locate a free file handle, open and read the copy of the INF file 
  $Fh=freefilehandle()
  If open($Fh,'%temp%\addprinter.txt',0) = 0
    $Found = 0
    $Line=ReadLine($Fh)      
    While Not @ERROR And Not $Found
      $Found = InStr($Line, $PrinterType)
      $Line = ReadLine($Fh)
    Loop
    $ = Close($Fh)
 
    If Not $Found
      Exit -2						; complain if the specified printer is not in the INF file 
    Else
      If $PrinterName = ''
        $PrinterName = $PrinterType			; use default description if none specified 
      EndIf
 
      If $Target = ''
        $Target = '\\'+ @WKSTA			; default to local system if target was not specified 
      Else 
        If left($Target, 2) <> '\\'
          $Target = '\\' + $Target			; make sure leading slashes are present 
        EndIf
      EndIf
 
      Select
       ; PrintServer connection 
       Case left($Port,2) = '\\'
        $PrintServer = 1
        $PrinterName = $Port
 
       ; IP printer connection 
       Case InStr($Port,'.')
        If InStr($Port,':')
          $Port=Split($port,':')[0]
          $LPRQueue=split($port,':')[1]
        EndIf
 
        $IPPrinterKey = $Target + '\HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\' + $PortName
        If Not KeyExist($IPPrinterKey)
          If $LPRQueue ; LPR 
            If WriteValue($IPPrinterKey,'Protocol','00000002','REG_DWORD') Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'Version','00000001','REG_DWORD')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'Double Spool','00000001','REG_DWORD')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'Queue',$LPRQueue, 'REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'HostName','', 'REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'IPAddress',$Port,'REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'HWAddress','','REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'PortNumber','00000203','REG_DWORD')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'SNMP Community','public','REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'SNMP Enabled','00000001','REG_DWORD')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'SNMP Index','00000001','REG_DWORD')  Exit @ERROR EndIf
          Else ; RAW 
            If WriteValue($IPPrinterKey,'Protocol','00000001','REG_DWORD') Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'Version','00000001','REG_DWORD')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'HostName','', 'REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'IPAddress',$Port,'REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'HWAddress','','REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'PortNumber','00009100','REG_DWORD')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'SNMP Community','public','REG_SZ')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'SNMP Enabled','00000001','REG_DWORD')  Exit @ERROR EndIf
            If WriteValue($IPPrinterKey,'SNMP Index','00000001','REG_DWORD')  Exit @ERROR EndIf
          EndIf
        Else
        EndIf
 
        $objService = Getobject('WinNT://' + SubStr($Target, 3) + '/Spooler, Service')
        If @ERROR
          Exit -4
        EndIf
 
        ; cycle the print spooler service 
        $objService.stop			; stop the spooler service 
        $ = 25					; set loop counter 
        Do
          Sleep 0.2				; wait until it is stopped, up to 5 seconds 
          $ = $ - 1
        Until $objService.status = 1 Or $ = 0
 
        If $ = 0 And $objService.status = 1	; failed to stop service in a timely manner 
          Exit -5
        EndIf
 
        $objService.start			; start the spooler service 
 
       ; Serial/Parallel port direct connection 
       Case UCase(left($Port, 3)) = 'LPT' Or UCase(left($Port, 3)) = 'COM'
        If Right($Port, 1) <> ':'
          $Port = $Port + ':'
        EndIf
        If Val(Left(Right($Port, 2), 1)) = 0
          Exit -1 
        EndIf
 
       ; Print to file 
       Case ucase(left($Port, 4)) = 'FILE'
        If Right($Port, 1) <> ':'
          $Port = $Port + ':'
        EndIf
 
       ; unknown option 
       Case 1
        Exit -1
 
      EndSelect
 
      If $PrintServer
        If AddPrinterConnection($Port)		; add a print server connection 
          Exit @ERROR    
        EndIf
      Else					; create a new printer device 
        $PrinterCmd = 'rundll32 printui.dll,PrintUIEntry /if /b "' + $PrinterName + '" /c "' + $Target + '" ' + 
                      '/f "' + $DriverInf + '" /r "' + $PortName + '" /m "' + $PrinterType + '" /u' + $AutoShare
;$PrinterCmd ? 
        Shell $PrinterCmd
      EndIf
 
      If $Default				; should we set default printer status? 
        If SetDefaultPrinter($PrinterName)
          Exit @ERROR
        EndIf
      EndIf 
 
      $AddPrinter = 1				; return success 
    EndIf
  Else
    Exit -3
  EndIf
 
EndFunction