VBScript MapNetworkDrive错误处理

时间:2016-06-12 16:49:09

标签: vbscript error-handling

我试图在VBScript中编写一个小脚本,纯粹是为了我的家庭使用,它在Macrium Reflect中的预定备份之前运行。

我遇到了一个看似很小的问题,那就是网络驱动器物理断开连接时的错误处理,即没有连接电缆。

当脚本检查驱动器是否已连接时,如果未连接驱动器,则会显示一条消息,告知用户连接电缆并按YES。

现在,一切顺利的用户都会按要求连接电缆,然后按下YES按钮,但我想抓住按下YES的时间,然后再连接驱动器的电缆。

在代码中有一个'On Error Resume Next'来掩盖这种可能性,所以我注释掉了这一行&事实上我在第40行得到了错误'找不到网络路径':

objNetwork.MapNetworkDrive strDriveLetter, strRemotePath, _

我想使用此捕获的错误向用户显示驱动器尚未连接的警报,请连接并重试&保持重试直到驱动器实际连接为止。

我的问题是我似乎找不到添加任何错误处理代码的位置来显示此消息。

这是我的代码:

Option Explicit
Dim strDriveLetter, strRemotePath, strUser, strPassword, strProfile, strName, objNetwork, objShell, CheckDrive, AlreadyConnected, intDrive

' The section sets the variables. 
strDriveLetter = "X:" 
strRemotePath = "\\192.168.1.1\shared"
strUser = "user"
strPassword = "password"
strProfile = "true"
strName = "Backup Drive"

' This sections creates two objects:
' objShell and objNetwork and counts the drives
Set objShell = CreateObject("WScript.Shell") 
Set objNetwork = CreateObject("WScript.Network") 
Set CheckDrive = objNetwork.EnumNetworkDrives() 

' This section deals with a For ... Next loop
' See how it compares the enumerated drive letters
' with strDriveLetter
On Error Resume Next
AlreadyConnected = False 
For intDrive = 0 To CheckDrive.Count - 1 Step 2 
If CheckDrive.Item(intDrive) =strDriveLetter _
Then AlreadyConnected = True
Next 

If AlreadyConnected = False Then 

Dim result
result = MsgBox("A Backup Is Now Due But The Drive Is Not Connected." & vbNewLine & vbNewLine & "Please Connect The Drive & Press YES To Continue." & vbNewLine & vbNewLine & "If You Wish To Postpone Backup Then Press NO Now.", 4 + 32, "BACKUP DRIVE NOT CONNECTED")
If result = 7 Then
WScript.Quit
Else
Call MapDRV
End If

Sub MapDRV()
Set objNetwork = WScript.CreateObject("WScript.Network") 
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath, _
strProfile, strUser, strPassword
Set objShell = CreateObject("Shell.Application")
objShell.NameSpace(strDriveLetter).Self.Name = strName
End Sub

WScript.Quit

错误处理代码就是这样的:

If Err.Number <> 0 Then
    'error handling:
    'ALERT USER HERE
Err.Clear
End If

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:2)

Err Object (VBScript)参考没有给出有用的指导。您需要为每个run-time error倾向操作单独捕获错误或成功。
通用规则(best practice):通过On Error GoTo 0禁用错误处理,并仅为可疑的操作启用它。

例如,我可能有多个原因导致MapNetworkDrive method失败(服务器脱机,用户被阻止,错误/更改密码等):

Sub MapDRV
  Dim errResult
  Set objNetwork = WScript.CreateObject("WScript.Network")
  errResult = ""
  On Error Resume Next
  objNetwork.MapNetworkDrive strDriveLetter, strRemotePath _
                      , strProfile, strUser, strPassword
  If Err.Number = 0 Then
    On Error GoTo 0
    Set objShell = CreateObject("Shell.Application")
    objShell.NameSpace(strDriveLetter).Self.Name = strName
  Else
    errResult = Err.Number & " 0x" & Hex(Err.Number) & " " & Err.Source
    errResult = errResult & vbNewLine & Err.Description
    On Error GoTo 0
    MsgBox errResult, vbOKOnly + vbCritical, "Error occurred"
  End If
End Sub

然后整个脚本可能如下所示:

Option Explicit
On Error GoTo 0

Dim strResult: strResult = Wscript.ScriptName

Dim strDriveLetter, strRemotePath, strUser, strPassword, strProfile , strName _
  , objNetwork, objShell, CheckDrive, AlreadyConnected, intDrive

' The section sets the variables. 
strDriveLetter = "X:" 
strRemotePath = "\\192.168.1.1\shared"
strUser = "user"
strPassword = "password"
strProfile = "true"
strName = "Backup Drive"

' This sections creates two objects:
' objShell and objNetwork and counts the drives
Set objShell = CreateObject("WScript.Shell") 
Set objNetwork = CreateObject("WScript.Network") 

' This section deals with a For ... Next loop
' See how it compares the enumerated drive letters with strDriveLetter
Dim result, toShare

AlreadyConnected = False
Do While AlreadyConnected = False
  strResult = strResult & vbNewLine & "--- new check"
  AlreadyConnected = False
  Set CheckDrive = objNetwork.EnumNetworkDrives() 
  For intDrive = 0 To CheckDrive.Count - 1 Step 2 
    If CheckDrive.Item(intDrive) = strDriveLetter Then
      AlreadyConnected = True
      toShare = CheckDrive.Item(intDrive + 1)
    End If
    strResult = strResult & vbNewLine & CheckDrive.Item(intDrive)
    strResult = strResult & vbTab & CheckDrive.Item(intDrive + 1)
  Next 
  If AlreadyConnected Then Exit Do
  result = MsgBox("A Backup Is Now Due But The Drive Is Not Connected." _
    & vbNewLine & vbNewLine & "If you wish to ..." _
    & vbNewLine & vbTab & "... postpone backup then press ABORT." _
    & vbNewLine & vbTab & "... backup to " & strRemotePath & " then press RETRY." _
    & vbNewLine & "Otherwise, please connect the drive & press IGNORE to continue." _
      , vbAbortRetryIgnore + vbQuestion, "BACKUP DRIVE NOT CONNECTED")
  Select Case result
  Case vbAbort
    Call scriptQuit
  Case vbRetry
    Call MapDRV
  Case Else
    ' The Case Else clause is not required
  End Select
Loop

  strResult = strResult & vbNewLine & "copy here to " & toShare 

Sub MapDRV
  ' no need to redefine: WshNetwork Object is already defined
  ' Set objNetwork = WScript.CreateObject("WScript.Network")
  Dim errResult
  On Error Resume Next
  objNetwork.MapNetworkDrive strDriveLetter, strRemotePath _
                      , strProfile, strUser, strPassword
  If Err.Number = 0 Then
    On Error GoTo 0
    Set objShell = CreateObject("Shell.Application")
    objShell.NameSpace(strDriveLetter).Self.Name = strName
  Else
    errResult = Err.Number & " 0x" & Hex(Err.Number) & " " & Err.Source
    errResult = errResult & vbNewLine & Err.Description
    On Error GoTo 0
    MsgBox errResult, vbOKOnly + vbCritical, "Error occurred"
    strResult = strResult & vbNewLine & vbNewLine & errResult
  End If
End Sub

Call scriptQuit

Sub scriptQuit
  Wscript.Echo strResult
  Wscript.Quit
End Sub

请注意,strResult变量仅用于调试目的,以查看下一个输出:

==> cscript D:\VB_scripts\SO\37776762.vbs
37776762.vbs
--- new check
Y:      \\S-PC\VB_scripts_help

-2147024843 0x80070035 WSHNetwork.MapNetworkDrive
The network path was not found.

--- new check
Y:      \\S-PC\VB_scripts_help

--- new check
Y:      \\S-PC\VB_scripts_help
X:      \\S-PC\test
copy here to \\S-PC\test

==>

以上输出对应下一步:

  • 运行脚本
  • 第一个--- new check找到Y:映射磁盘;然后调用重试操作失败(找不到网络路径);
  • 第二个--- new check再次找到Y:映射磁盘;然后手动映射磁盘X:,然后调用忽略操作;
  • 第三个--- new check找到了Y:X:映射的磁盘;
  • Do While循环退出,脚本继续执行下一步操作。

为完整起见,以下输出显示已调用的 Abort 操作:

==> net use x: /delete
x: was deleted successfully.

==> cscript D:\VB_scripts\SO\37776762.vbs
37776762.vbs
--- new check
Y:      \\S-PC\VB_scripts_help

==>