Tuesday, October 11, 2005


How to shut down COM+ applications with high call times with VB and VBScript

I posted earlier this year on How to get COM+ call times from VB and VBScript mentioning that it is possible to automatically shut down/recycle components with high call times using the COM+ Admin API. With VBScipt it is very  easy. The script below can be used from VB, VBScript or even an ASP page.

It uses the egilh.comtracker to get the COM+ call times in XML:


























It loads the XML in a DOM using MSXML 3.0 and checks the responseTimes. It uses the COM+ Admin API to shut down the application if the call time is higher than the configured MAX_CALL_TIME and there are objects in call. The ShutDownApplication method works on Windows 2000 as well as Windows 2003. It has the same "brutal" effect as right clicking a COM+ application and selecting "shut down"; clients currently in call will get a COM+ error. With Windows 2003 it is possible to use recycling which routes new request to a new application instance but lets existing calls finish.

Option Explicit


Const MAX_CALL_TIME = 10000  'Max allowed call time in miliseconds

Const CHECK_INTERVAL = 5000  'How often we should check the call times

Const RECYCLE_REASON = 408  'The reason for the recyle. Any number is OK



'Never ending main loop that monitors the call time

Do While True





Private Sub checkCallTimes()


'Purpose: Check the call times and shut down applications that have too high call times

    Dim oTracker 'As Object

    Dim sResult 'As String

    Dim oDOM 'As DOMDocument30

    Dim oNode 'As MSXML2.IXMLDOMNode

    Dim sProgID 'As String

    Dim lResponseTime 'As Long

    Dim lInCall 'As Long

    Dim oApp 'As MSXML2.IXMLDOMNode

    Dim bHighCallTimes 'As Boolean


     'Get the com+ call times

    oTracker = CreateObject("egilh.ComTracker")

    sResult = oTracker.getStatistics()

    oTracker = Nothing


    bHighCallTimes = False


    'Check call times

    oDOM = CreateObject("MSXML2.DomDocument.3.0")


    For Each oNode In oDOM.selectNodes("/applications/application/classes/class")

        lInCall = CLng(oNode.selectSingleNode("inCall").Text)

        lResponseTime = CLng(oNode.selectSingleNode("responseTime").Text)


        ' Check if we should recycle

        If lResponseTime > MAX_CALL_TIME And lInCall > 0 Then

            'Log that we are recycling

            sProgID = oNode.selectSingleNode("progID").Text

            WScript.Echo(Now() & " Shutting down '" & sProgID & _

                              "' because of high call time: " & lResponseTime)


            'We shut down the parent process: ../../processID

            oApp = oNode.parentNode.parentNode


            bHighCallTimes = True

        End If



    If Not bHighCallTimes Then WSCript.Echo(Now() & " Call Times OK")

End Sub



Private Sub shutDownApplication(ByVal appGuid)


'Purpose: Shut down an application

'Description: Shuts down a com+ application identified by its guid.

Dim adminCatalog 'As COMAdmin.COMAdminCatalog

Dim appInstanceGUID 'As Object


    adminCatalog = CreateObject("COMAdmin.COMAdminCatalog")





    adminCatalog = Nothing

End Sub


  1. How to get CALL Times in VBFebruary 4, 2008 at 10:11 PM

    How to get CALL Times in VB. I appreciate the work you have done. Its really helped me get some insight. But, I cannot use your Com Tracker dll and need the code in plain VB. Can somebody convert the code(C++,C#,VB.NET) into VB please.



  2. Sorry you cannot do this using plain VB.

    What prevents you from using the ComTracker DLL?

  3. My manager is looking for a solution in simple ASP pages.so VBScript would be the option (or VB code can be pushed to one if the existing dlls). They would not deploy an additional dll onto the servers :(



  4. There is no way to do this from ASP only. You should be able to do it from ASP.NET

    Another option is to use ComTracker to query remote machines.

  5. I have tried using the VB.NET code for remote servers from one of the posts here. but when I do "tlbexp" and export the dll into tlb, and try and register the dll,it does not get registered in the COM+ services. Is there some method to do this.

    OR can you please give the cpp version with remote server name as input to the function getStatistics(), and i am new to VC++ environment so can you give the complete cpp file so that i can make the dll myself in VC++.

    My aim is to use ASP pages to create the object locally which will getStats from some other server without the dll deployed on that server.