我遇到了一个VBScript的问题,它从Excel工作表上的列表中查找计算机上的打印机,然后通过WMI找到它们。它通过IP地址名称匹配它们,然后写入我可以安装它们的批处理文件。我的问题是,当我有一台计算机关闭时,我得到一个462错误然后被清除,然后再次写入前一台计算机的打印机。我对此很陌生,所以我不确定我是否只是缺少一些非常基本的东西。
Batch = "printerOutput.txt"
Const ForWriting = 2 'Set to 8 for appending data
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(Batch, ForWriting)
On Error Resume Next
Dim printerDictionary 'Create Printer dictionary of names and IP addresses
Set printerDictionary = CreateObject("Scripting.Dictionary")
printerDictionary.Add "Printer","xxx.xxx.xxx.xxx"
Set objExcel_1 = CreateObject("Excel.Application")
' Statement will open the Excel Workbook needed.
Set objWorkbook = objExcel_1.Workbooks.Open _
("x\p.xls")
If Err.Number <> 0 Then
MsgBox "File not Found"
Wscript.Quit
End If
'Checks for errors
f = 1 'Sets variable that will loop through Excel column
Do
' Msgbox f,, "Begining of Do Loop"
strComputer = objExcel_1.Cells(f, 1).Value
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")
For Each objPrinter in colPrinters 'For ever objPrinter found in the computers WMIService
If Err.Number = 0 Then
objFile.WriteLine Err.Number
If InStr(ObjPrinter.PortName,".") = 4 then 'If the printers IP port name is written like 128.xxx.xxx.xxx
'MsgBox ObjPrinter.Name & " " & ObjPrinter.PortName,, "IfStatement"
PrtDict ObjPrinter.PortName, StrComputer
ElseIf InStr(ObjPrinter.PortName,"_") = 3 Then 'If the printers IP port name is written like IP_128.xxx.xxx.xxx
cleanIP = GetIPAddress(objPrinter.PortName) 'Clean IP
PrtDict cleanIP, StrComputer
End If
Else
objFile.WriteLine "REM " & strComputer & " - Error: " & err.number
Err.Clear
End If
Next
f = f + 1
Loop Until objExcel_1.Cells(f, 1).Value = ""
objExcel_1.ActiveWorkbook.Close
ObjExcel_1.Quit
Function PrtDict(PrtMn, CMP) 'Loops through the dictionary to find a match from the IP address found
For Each x in printerDictionary
'MsgBox PrtMn & "=" & printerDictionary.Item(x),,"InPtrDict"
If printerDictionary.Item(x) = PrtMn Then
objFile.WriteLine "psexec -u \%1 -p %2 " & CMP & " path\" & x & ".bat"
End If
Next
End Function
'100
Function GetIPAddress(Address) 'For cleaning up IP address with names like IP_128.xxx.xxx.xxx
IPtext = InStr(Address,"_")
IPaddress = len(Address) - IPtext
GetIPAddress = Right(Address,IPaddress)
End Function
答案 0 :(得分:0)
这是怎么回事:
On Error Resume Next
这样可以对脚本的其余部分进行错误处理(或者更确切地说是错误抑制),因为它永远不会被禁用。
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
此命令失败,因为无法访问strComputer
。由于错误,变量Err
已设置且objWMIService
保留其先前值。
Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")
此命令成功并从之前的计算机重新读取打印机列表,因为objWMIService
仍然引用该计算机。
For Each objPrinter in colPrinters
脚本进入循环,因为colPrinters
已填充上一台计算机的打印机(再次),...
If Err.Number = 0 Then ... Else ... End If
...但由于Err
仍然设置,脚本会进入Else
分支,报告并清除错误:
objFile.WriteLine "REM " & strComputer & " - Error: " & err.number
Err.Clear
然后脚本进入循环的下一次迭代。 Err
现已清除,因此colPrinters
中的其余打印机正在正常处理。
全球On Error Resume Next
是万恶之源。不要这样做。 EVER。 强>
如果绝对必须使用On Error Resume Next
,请在本地启用错误处理,将一些实际的错误处理代码放在适当的位置,然后立即禁用错误处理。在你的情况下,可以像这样实现它:
...
Do
strComputer = objExcel_1.Cells(f, 1).Value
On Error Resume Next
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
If Err Then
objFile.WriteLine "REM " & strComputer & " - Error: " & err.number
Set objWMIService = Nothing
End If
On Error Goto 0
If Not objWMIService Is Nothing Then
Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")
For Each objPrinter in colPrinters
...
Next
f = f + 1
End If
Loop Until objExcel_1.Cells(f, 1).Value = ""
...