Within a network, you can connect a local workstation to a network printer. This task is commonly known as printer mapping. Windows can connect directly to a network printer or map a local port to a remote printer. (The latter approach is recommended only if you need support for network printing for an MS-DOS program.)
In WSH 2, the WshNetwork object provides two methods, AddPrinterConnection and AddWindowsPrinterConnection, for adding a network printer connection to Windows. AddWindowsPrinterConnection is the recommended method for connecting to a network printer (unless you need network printing support for MS-DOS applications).
First you retrieve an instance of the WshNetwork object using the following (VBScript) command:
Set WshNetwork = WScript.CreateObject("WScript.Network") |
Then you use the following syntax for AddWindowsPrinterConnection in Windows 95 and Windows 98:
WshNetwork.AddWindowsPrinterConnection(strPrinterPath, strDriverName[, strPort]) |
The first parameter must contain the printer path in UNC format (as in \\ROM\HP500). The second parameter specifies the name of the printer driver, and the third (optional) parameter specifies the local port to be remapped (such as LPT1).
NOTE
In Windows 95 and Windows 98, the printer driver must be installed on the local machine in order for the AddWindowsPrinterConnection method to work. Otherwise, Windows returns the error message "Unknown printer driver."
In Windows NT and Windows 2000, the AddWindowsPrinterConnection method has just one parameter:
WshNetwork.AddWindowsPrinterConnection(strPrinterPath) |
This parameter must contain the path to the network printer (as in \\ROM\HP500). No local port or printer driver is required.
If you intend to print from MS-DOS programs, you can also map a local printer port to a network printer in a WSH script using the AddPrinterConnection method of the WshNetwork object, as follows:
Set WshNetwork = WScript.CreateObject("WScript.Network") WshNetwork.AddPrinterConnection "LPT1", "\\ROM\HP500" |
The first line creates an instance of the WshNetwork object and assigns it to the object variable WshNetwork. The next line applies the AddPrinterConnection method to this object. This method requires at least two parameters. The first parameter contains the name of the local resource (such as LPT1 or LPT2) as a string, and the second parameter defines the remote name of the network resource to be mapped, in UNC notation. (UNC stands for Universal Naming Convention, which specifies a reference to a network in the format \\station name\path.) For example, on my test machine, I can select the resource \\ROM\HP500, which references the printer \HP500, which is released on the workstation \\ROM for sharing.
Listing 11-3 shows how to use VBScript to connect a printer to a network device in Windows NT or Windows 2000.
Listing 11-3 MapPrinter1.vbs
'*************************************************** ' File: MapPrinter1.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Connecting a printer to a network printer using ' the AddWindowsPrinterConnection method in ' Windows NT or Windows 2000 '*************************************************** Option Explicit ' Const printer = "\\ROM\HP500" Const printer = "\\Wien\HPLJ" Dim Text, Title, icon Dim WshNetwork ' Object variable Title = "WSH sample - by G. Born" ' Create a new WshNetwork object to access network properties. Set WshNetwork = WScript.CreateObject("WScript.Network") On Error Resume Next WshNetwork.AddWindowsPrinterConnection printer Select Case Err.Number Case 0 Text = "Printer connected to """ & printer & """." icon = vbInformation Case -2147023688 Text = "Error: Network resource """ & _ printer & """ doesn't exist." icon = vbCritical Case -2147024811 Text = "Error: Mapping to """ & printer & """ already exists." icon = vbCritical Case Else Text = "Error: Code " & Err.Number & " " & Err.Description icon = vbCritical End Select On Error GoTo 0 ' Enable run-time error handling. MsgBox Text, vbOKOnly + icon, Title '*** End |
To map a network printer to a local port (to support MS-DOS programs with network printing), you can use the AddPrinterConnection method of the WshNetwork object:
WshNetwork.AddPrinterConnection "LPT1", "\\ROM\HP500" |
The first parameter in the VBScript statement is the name of the local port, and the second parameter is a valid network resource in UNC format. You can establish a printer mapping permanently, over several sessions, or temporarily (where the mapping is lost during reboot). You can select the Reconnect At Logon check box in the Capture Printer Port dialog box during a manual printer mapping to force permanent printer capturing. You can also use the AddPrinterConnection method's third, optional, parameter for this purpose. If this parameter is set to True, the method establishes a persistent connection that's set up during each logon. The preceding statement establishes a temporary connection for the local user.
You can also use the AddPrinterConnection method to set up a printer mapping for any user. You pass the user's name in a fourth parameter and a password in an optional fifth parameter, as shown in the following statement, which creates a connection for the user Bill.
WshNetwork.AddPrinterConnection "LPT1", "\\ROM\HP500", , _ "Bill", "Pegasus" |
This statement omits the third parameter, so you must use a comma as a placeholder for the missing parameter. The method inserts the value False for the missing parameter, and you get a temporary mapping.
NOTE
It might seem useful to specify a user name and a password, but because these values are in a readable format in your script, anyone who has access to the script's source can see them. Therefore, it's better simply not to include passwords in a script.
The VBScript sample in Listing 11-4 uses AddPrinterConnection to establish a printer capture provided by the network client between the local port defined in the constant port and the network printer given in the constant printer. The script uses the On Error Resume Next statement to catch run-time errors. If the printer port is already captured, the script informs the user that the connection can't be made. You can extend this listing to force WSH to delete the current connection and establish a new mapping.
Listing 11-4 MapAddPrinterConnection.vbs
'************************************************************** ' File: MapAddPrinterConnection.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Mapping the printer port LPT1 to a network ' printer '************************************************************** Option Explicit ' Const printer = "\\ROM\HP500" Const printer = "\\Wien\HP500" Const port = "LPT1" Dim Text, Title, icon Dim WshNetwork ' Object variable Title = "WSH sample - by G. Born" ' Create a new WshNetwork object to access network properties. Set WshNetwork = WScript.CreateObject("WScript.Network") On Error Resume Next WshNetwork.AddPrinterConnection port, printer Select Case Err.Number Case 0 Text = "Printer """ & port & """ connected to """ & _ printer & """." icon = vbInformation Case -2147023688 Text = "Error: Network resource """ & printer & _ """ doesn't exist." icon = vbCritical Case -2147024811 Text = "Error: Mapping """ & port & """ to """ & _ printer & """ already exists." icon = vbCritical Case Else Text = "Error: Code " & Err.Number & " " & Err.Description icon = vbCritical End Select On Error Goto 0 ' Disable run-time error handling. MsgBox Text, vbOKOnly + icon, Title '*** End |
NOTE
If the script encounters an unknown error, the error code is reported. A negative error number (such as -2147023688) indicates a COM object error (because the high bit is set). Sometimes it's helpful to subtract vbObjectError from the negative value to get a more meaningful error code. Alternatively, you can convert the original decimal error number to a hexadecimal value. If the error isn't described in the VBScript help, you can search the Microsoft Knowledge Base (at http://www.microsoft.com) for error codes.
You can use the same methods for printer mapping in JScript. JScript 5 supports a try … catch block that you can use to trap run-time errors, as shown here:
try { WshNetwork.AddPrinterConnection("LPT1", "\\\\ROM\\HP500"); } catch (err) { if (err != 0) // Check error object. WScript.Echo("Error: " + err); } |
The try { ... } block contains all the statements that might cause run-time errors. You must enclose the statements within the block in braces. If one of the statements causes a run-time error, the error dialog box of the run-time system is suppressed and control is transferred to the catch statement, which assigns the error code to the error variable given as the parameter of the catch (err) statement. You can define any variable name for err.
The statements within the catch branch must also be enclosed in braces, to create a block. These statements handle the run-time error. The sequence just shown uses an if statement to check whether the content of the variable err is equal to 0. The sequence displays a user-defined error dialog box only if a run-time error occurs.
Listing 11-5 establishes a printer mapping. If a run-time error occurs, a user-defined error dialog box is shown.
Listing 11-5 MapPrinter.js
//************************************************** // File: MapPrinter.js (WSH sample in JScript 5) // Author: (c) G. Born // // Mapping the printer port LPT1 to a network // printer and trapping run-time errors //************************************************** var port = "LPT1" var printer = "\\\\WIEN\\HPLJ" // Create a new WshNetwork object to access network properties. var WshNetwork = WScript.CreateObject("WScript.Network"); // Catch run-time errors. try { // Try to add the connection. WshNetwork.AddPrinterConnection(port, printer); } catch (e) // Catch a possible run-time error. { if (e != 0) // Display a possible error message. WScript.Echo("Error connecting printer", port, "to", printer, "\n\nError code: " + e); WScript.Quit(); } WScript.Echo("Printer port \"" + port + "\" connected to \"" + printer); //*** End |
You can remove a printer connection by using the RemovePrinterConnection method of the WshNetwork object. This method has the following syntax:
object.RemovePrinterConnection strName, [bForce], [bUpdateProfile] |
The parameter strName can be a local resource (such as a printer port) or a remote printer. You can set the optional second parameter to a Boolean value of True or False to specify whether the connection should be removed if it's in use. You can also set the third parameter, bUpdateProfile, which is also optional, to True or False. If it's set to True, the mapping is removed from the user profile.
Listing 11-6 uses the RemovePrinterConnection method to remove a mapping from the local printer port LPT1.
Listing 11-6 UnMapPrinter.vbs
'**************************************************** ' File: UnMapPrinter.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Removing a printer mapping '**************************************************** Option Explicit Const port = "LPT1" Dim Text, Title, icon Dim WshNetwork ' Object variable Title = "WSH sample - by G. Born" ' Create a new WshNetwork object to access network properties. Set WshNetwork = WScript.CreateObject("WScript.Network") On Error Resume Next WshNetwork.RemovePrinterConnection port Select Case Err.Number Case 0 Text = "Printer """ & port & """ connection removed" icon = vbInformation Case -2147023688 Text = "Error: Network resource """ & printer & _ """ doesn't exist." icon = vbCritical Case Else Text = "Error: Code " & Err.Number & " " & Err.Description icon = vbCritical End Select On Error Goto 0 ' Disable run-time error handling. MsgBox Text, vbOKOnly + icon, Title '*** End |
You can use the EnumPrinterConnections property to display a list of mapped printers on a machine. This property returns a collection containing the currently defined printer mappings. The following code statement retrieves the printer mappings:
Set oDevices = WshNetwork.EnumPrinterConnections |
Once you retrieve the collection, you can use the variable oDevices(0) to find the name of the first printer port. The oDevices(1) variable contains the UNC name of the mapped network resource. This pattern continues, with the printer port in the even-numbered elements and the corresponding mapped network resource name in the odd-numbered elements.
Listing 11-7 uses a loop to process all entries in the collection and show the printer mappings in a dialog box (Figure 11-2). The step width in the loop is set to 2, and the local port and the network mapping are retrieved within each step.
Listing 11-7 ListPrinterMapping.vbs
'********************************************************** ' File: ListPrinterMapping.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Listing printer mappings using EnumPrinterConnections '********************************************************** Option Explicit Dim Text, Title, i Dim WshNetwork, oDevices ' Object variable Title = "WSH sample - by G. Born" ' Create a new WshNetwork object to access network properties. Set WshNetwork = WScript.CreateObject("WScript.Network") ' List mappings. Text = "Printer mapping" & vbCrLf Set oDevices = WshNetwork.EnumPrinterConnections For i = 0 To oDevices.Count - 1 Step 2 Text = Text & oDevices(i) & " " & oDevices(i+1) & vbCrLf Next MsgBox Text, vbOKOnly + vbInformation, Title '*** End |
Figure 11-2 A list of printer mappings (in Windows 2000)
The JScript version, ListPrinterMapping.js, is shown in Listing 11-8.
Listing 11-8 ListPrinterMapping.js
//******************************************************** // File: ListPrinterMapping.js (WSH sample in JScript) // Author: (c) G. Born // // Showing printer mappings using EnumPrinterConnections //******************************************************** // Create a new WshNetwork object to access network properties. var WshNetwork = WScript.CreateObject("WScript.Network"); // List mappings. Text = "Printer mapping \n"; var oDevices = WshNetwork.EnumPrinterConnections(); for (var i = 0; i <= oDevices.length-2; i = i+2) { Text = Text + oDevices(i) + " " + oDevices(i+1) + "\n"; } WScript.Echo(Text); //*** End |
WSH 2 also provides a SetDefaultPrinter method, whose parameter specifies a printer as the default printer:
Set WshNetwork = WScript.CreateObject("WScript.Network") WshNetwork.SetDefaultPrinter "\\Wien\HP500" |
NOTE
While experimenting with this method in Windows 2000, I found an irregularity. If the printer doesn't exist, the method causes a run-time error. My attempt to handle this run-time error using On Error Resume Next failed. If a run-time error occurs, the script terminates without any further messages even if you insert statements (such as If Err <> 0 Then or WScript.Echo Err.Code) to test the error code. As a result, the sample in Listing 11-9 doesn't contain any error handling.
Listing 11-9 lists in an input dialog box (shown in Figure 11-3) all printers found on a system. The user can enter a number to select a valid entry. The associated printer is then set as the default printer, and a dialog box reports this result.
Figure 11-3 Setting the default printer
Listing 11-9 DefaultPrinter.vbs
'***************************************************** ' File: DefaultPrinter.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Setting the default printer (in WSH 2) '***************************************************** Option Explicit Dim Text, Title, i, j, tmp, printer Dim WshNetwork, oDevices ' Object variable Title = "WSH sample - by G. Born" ' Create a new WshNetwork object to access network properties. Set WshNetwork = WScript.CreateObject("WScript.Network") ' Read all printers. Set oDevices = WshNetwork.EnumPrinterConnections Text = "Available printers" & vbCrLf j = oDevices.Count For i = 0 To j - 1 Step 2 Text = Text & (i/2) & vbTab Text = Text & oDevices(i) & vbTab & oDevices(i+1) & vbCrLf Next ' Show all available printers and allow a user selection. tmp = InputBox(Text, "Set default printer", 0) If tmp = "" Then WScript.Echo "No user input, aborted" WScript.Quit End If tmp = CInt(tmp) If (tmp < 0) Or (tmp > (j/2 _ 1)) Then WScript.Echo "Wrong value, aborted" WScript.Quit End If printer = oDevices(tmp*2 + 1) ' Select printer name. ' Set the default printer. WshNetwork.SetDefaultPrinter printer MsgBox "Set default printer to " & printer, _ vbOKOnly + vbInformation, Title '*** End |