Search code examples
excelvbawshwscript.shell

WScript.Shell crashes Excel


I am using WshShell to run a batch file from VBA within Excel.

  • The batch file is VERY simple, one line that runs a number crunching program. I can run the batch file directly without problems.
  • I am using WshShell or WScript.Shell because I want VBA to wait to load the results back in Excel once the calculation is done.
  • I have references to "Microsoft Scripting Runtime" and "Windows Script Host Object Model"
  • I have been using the same code for a long time. It worked fine until 2-3 weeks ago. Now it closes Excel. If I have a few spreadsheets opened, it closes them all.
  • I have two versions but they both crash at the "Set WinSh = ..." line. Excel is not responding for a few (~10) seconds and then it closes.
  • I am using Office 365 MSO (16.0.12527.21294) 32 bit. It is managed by my organization.
  • I tried the same code in Word and it crashes as well.

Anyone know if recent updates could do this? or of another method I could use?

The subs are:

Public Sub RunBatch(FPath As String)
    Dim WinSh As Object
    Dim StrCmd As String
    Dim ErrCode As Long
    Set WinSh = New WshShell
    StrCmd = Chr(34) & FPath & Chr(34)
    ErrCode = WinSh.Run(StrCmd, WindowStyle:=1, WaitOnReturn:=True)
End Sub
  
Public Sub RunBatch2(FPath As String)
    Dim WinSh As Object
    Set WinSh = VBA.CreateObject("WScript.Shell")
    WinSh.Run FPath, 1, True
End Sub

Solution

  • The source of the problem is either an update or a change in the security policies of Cisco AMP. This blocks the use of Windows Scripting Host. The security department of my organisation is working to find a solution to the problem.

    In the meantime, I found a way around it. I use shell (which does not wait for the batch to end before resuming the VBA code) to run the batch which writes a simple text file at the end of the process and I wait for the text file to appear in 1 second increments. It is crude but it works so far.

    Public Sub OneRunBatch()
    
    Dim xlWB As Workbook
    Dim fso1 As New FileSystemObject
    Dim BatFile As Object
    Dim IsDone As Boolean
    Dim OutFileName As String
    Dim DoneFileName As String
    Dim OutPath As String
    Dim DeleteBatFile As Boolean
    
    Set xlWB = ThisWorkbook
    OutPath = xlWB.Path
    OutFileName = "HW.bat"
    DoneFileName = "Done.txt"
    DeleteBatFile = False
    
    Set BatFile = fso1.CreateTextFile(OutPath & "\" & OutFileName)
    BatFile.WriteLine "cd /d " & OutPath
    BatFile.WriteLine "echo Hello World"
    BatFile.WriteLine "dir > " & DoneFileName
    BatFile.Close
    
    IsDone = False
    Call Shell(OutPath & "\" & OutFileName, vbNormalFocus)
    
    Do Until IsDone
        If fso1.FileExists(OutPath & "\" & DoneFileName) Then IsDone = True
        Application.Wait (Now + TimeValue("00:00:01"))
    Loop
    
    fso1.DeleteFile (OutPath & "\" & DoneFileName)
    If DeleteBatFile Then fso1.DeleteFile (OutPath & "\" & OutFileName)
    
    End Sub