运行后无法删除VBScript文件

时间:2013-12-03 12:34:38

标签: vba file-io

我正在使用VBA模拟多线程,代码会创建多个vbs文件并运行它们。但是我完成后无法删除它们,它说“找不到脚本文件”这是我的代码:

' Write VBScript file to disk
sFileName = ActiveWorkbook.Path & "\Thread_" & agentNr & ".vbs"
intFileNum = FreeFile
Open sFileName For Output As intFileNum
Print #intFileNum, s
Close intFileNum
' Run VBScript file
Set wshShell = CreateObject("Wscript.Shell")
wshShell.Run """" & sFileName & """"


Kill sFileName
Set wshShell = Nothing

有什么想法吗?感谢

2 个答案:

答案 0 :(得分:2)

在我们的原始代码中,由于它处于异步模式,因此在删除脚本文件之前,Shell尚未读取该脚本文件。

现在我建议使用自毁模式。

作为评论,我们在异步模式下再次运行.vbs,但脚本文件将在vbscript的末尾删除,即在脚本本身内部。删除指令附加在要创建的VBScript的末尾:

Sub sof20351356RunVbScript()
  Dim intFileNum As Integer
  Dim agentNr As Long
  Dim sFileName As String, s As String
  Dim wshShell

  agentNr = 5

  ' Write VBScript file to disk
  sFileName = ActiveWorkbook.Path & "\Thread_" & agentNr & ".vbs"

  '
  ' In the file, we do our job normally,
  ' at the end, we kill the vbscript inside the script itself:
  '
  s = "MyVar = 1" & vbCrLf _
    & "'... do foo bar" & vbCrLf

  '
  ' now add the Killing order:
  s = s _
    & "Set fso = CreateObject(""Scripting.FileSystemObject"")" & vbCrLf _
    & "fso.DeleteFile """ & sFileName & """" & vbCrLf


  intFileNum = FreeFile
  Open sFileName For Output As intFileNum
  Print #intFileNum, s
  Close intFileNum
  ' Run VBScript file
  Set wshShell = CreateObject("Wscript.Shell")
  '
  ' in synchronous mode:
  'wshShell.Run """" & sFileName & """", 0, True

  '
  ' in asynchronous mode:
  wshShell.Run """" & sFileName & """", 0, False


  'Kill sFileName
  Set wshShell = Nothing

End Sub

参考:http://msdn.microsoft.com/en-us/library/d5fk67ky(v=vs.84).aspx

正如我测试所证实的那样,在脚本开始运行之前,它在内存中以100%的内存读取(Windows脚本解释器),因此文件本身在开始执行时没有任何重要性。因此,您甚至可以在VBscript开头添加销毁指令,然后再进行真正的工作。

但cmd.exe .bat文件无法像这样处理。

答案 1 :(得分:0)

您正在尝试删除当前正在运行的脚本文件。这可能是造成问题的原因。

如何使用wshShell.Exec方法代替Run?这样,您可以跟踪VBScript是否已完成运行,并延迟删除VBS文件,直到完成为止。

概念验证,未经测试:

Dim oExec
Set oExec = wshShell.Exec("sFileName")
'Can launch more processes here...

'Now check if oExec process is done
Do While oExec.Status = 0
    'oExec process not done yet...
     WScript.Sleep 100
Loop
'It's done. Delete the file.
Kill sFileName

这当然只是一个过程的简单例子。您可以启动更多这些并将其句柄(如oExec)存储在数组/集合/字典中。然后定期检查所有句柄,直到它们都完成运行。