【问题标题】:Skipping computers with error跳过错误的计算机
【发布时间】:2013-04-18 21:48:58
【问题描述】:

我在使用 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

【问题讨论】:

    标签: vbscript wmi-service


    【解决方案1】:

    会发生什么:

    1. On Error Resume Next

      这将为脚本的其余部分启用错误处理(或者更确切地说是错误抑制),因为它从未被禁用。

    2. Set objWMIService = GetObject("winmgmts:\\" &amp; strComputer &amp; "\root\cimv2")

      此命令失败,因为无法访问strComputer。由于错误,设置了变量 Err 并且 objWMIService 保留其先前的值

    3. Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")

      此命令成功并从前一台计算机重新读取打印机列表,因为objWMIService 仍然指的是那台计算机。

    4. For Each objPrinter in colPrinters

      脚本进入循环,因为colPrinters 被前一台计算机的打印机(再次)填充,......

    5. If Err.Number = 0 Then ... Else ... End If

      ...但是因为Err仍然设置,脚本进入Else分支,在那里报告并清除错误:

      objFile.WriteLine "REM " & strComputer & " - Error:  " & err.number
      Err.Clear
      
    6. 然后脚本进入循环的下一个迭代。 Err 现已被清除,因此colPrinters 中的其余打印机正在正常处理中。

    全球On Error Resume Next是万恶之源。不要这样做。 永远。

    如果您绝对必须使用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 = ""
    ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多