Search code examples
windowsexcelvbscriptactivexwsh

Share Excel.Application executable among multiple WSF processes?


I have a system that launches 50 or so VBS scripts via WSF, that need to stay there until another part of the system connects to them, then they act as servers for a bit until the peer disconnects, then they exit and get restarted.

For initialization purposes, they all use an EXCEL.EXE to read a large number of parameters from a spreadsheet, via

Set objExcel = CreateObject("Excel.Application")

We can't afford to have 50 EXCEL.EXEs running at once, so the restarts are sequentialized, so that there should never be more than one EXCEL.EXE running: usually zero, as they are only used for 15-20 seconds and then released.

However sometimes things go wrong, the WSF scripts exit, and the EXCEL.EXE that it starts stays there. So we do see up to a dozen EXCEL.EXE processes.

My question is about using GetObject() instead of CreateObject(). Would it be possible to use GetObject() so that if there already was an EXCEL.EXE running, it would use that one instead of starting a new one? And if so what other steps are necessary?

There is also a supplementary question here about why the EXCEL.EXEs persist after the VBS that started them has exited, but I can imagine ways in which the VBS could exit (or be killed) that would allow that.

Note that the question is also partly about the re-entrancy of EXCEL.EXE, which I have no information about.

I'm not the author of these scripts, and I'm not very strong in VBS as far as external objects go, so it is is entirely possible that I'm asking a trivial question here.


Solution

  • Usage of GetObject() is documented in this old KB article. Error handling is required to get the first instance created. Like this:

    Dim excel
    On Error Resume Next
    Set excel = GetObject(, "Excel.Application")
    If Err.number = 429 Then
       Set excel = CreateObject("Excel.Application")
    End If
    If Err.number <> 0 Then
        WScript.Echo "Could not start Excel: " & err.Description
        End
    End If
    '' etc
    

    However, seeing zombie Excel.exe processes surviving is a broad concern, it strongly suggests that the scripting runtime is not exiting normally. Perhaps error handling in your existing scripts is less than ideal, that's not likely to get better when you slam a single instance with multiple scripts. Excel does get pretty cranky when it cannot keep up. Using the OpenXML api or Excel Services are the better way to go about it.