Building from Paul Long's post on stopping a Netmon3 capture on a particular event, we're going to re-jig it so that we can run ADPLUS soon after a particular event is logged.

This won't produce a dump at the exact moment of the event log (which more often is what would be most useful for debugging purposes), but for the case I'm working on, I'm mainly interested in the state of the process at around or after that time; it's an intermittent problem that we're not confident we can catch quickly enough manually.

An alternative approach would be to attach, set a break on the Windows event logging function and evaluate the arguments passed to it; that's not what I'm doing here, and this has the advantage of being able to survive process recycling without special care.

EvtMon.vbs:

' evtmon.vbs
'
http://blogs.technet.com/netmon/archive/2007/02/22/eventmon-stopping-a-capture-based-on-an-eventlog-event.aspx
'======================================================================
' Print out the help when something is not typed in correctly or when
' nothing at all is typed in.

Public Sub PrintHelp
    Wscript.Echo "Usage:"
    Wscript.Echo "  EvtMon EventNumber [LogFile]"
    Wscript.Echo "    LogFile is optional.  If used, the eventlog name"
    Wscript.Echo "    file ie, application, system, security, etc..."
End Sub

' Get the arguments.  Check for event nubmer and log file as arugments
Set objArgs = WScript.Arguments

' See how many arguments we have and colect them.
if objArgs.Count < 1 OR objArgs.Count > 2 Then
    PrintHelp
ElseIf objArgs.Count > 1 Then
    EventNumber = objArgs(0)
    LogFile = objArgs(1)
Else
    EventNumber = objArgs(0)
    LogFile = ""
End If

If EventNumber <> "" Then

    strComputer = "."

    ' Attatch to the WMI Service
    Set objWMIService = GetObject("winmgmts:{(Security)}\\" & _
            strComputer & "\root\cimv2")

    ' if the LogFile is populated add this to our query.  Create a
    ' Event Log monitoring object and send it a query.
    If LogFile = "" Then
        Set colMonitoredEvents = objWMIService.ExecNotificationQuery _   
            ("Select * from __InstanceCreationEvent Where " _
                & "TargetInstance ISA 'Win32_NTLogEvent' " _
                    & "and TargetInstance.EventCode = '" _
                    & EventNumber & "'")
    Else
        Set colMonitoredEvents = objWMIService.ExecNotificationQuery _   
            ("Select * from __InstanceCreationEvent Where " _
                & "TargetInstance ISA 'Win32_NTLogEvent' " _
                    & "and TargetInstance.EventCode = '" _
                    & EventNumber _
                    & "' and TargetInstance.LogFile = '" _
                    & LogFile & "'")
    End If

    ' Create an object which returns when the next event occurs.
    Set objLatestEvent = colMonitoredEvents.NextEvent
    ' Print some info based on the event log we encountered.
    Wscript.Echo objLatestEvent.TargetInstance.User
    Wscript.Echo objLatestEvent.TargetInstance.TimeWritten
    Wscript.Echo objLatestEvent.TargetInstance.Message
    WScript.Echo objLatestEvent.TargetInstance.Logfile
    Wscript.Echo
End If

And the control batch file DUMPONEL.CMD, that does the rest of the work, also cannibalized from Paul's post!

DUMPONEL.CMD:

@echo off
if "%1"=="" goto Usage
if "%2"=="" goto Usage

cscript //NoLogo EvtMon.vbs %2 %3
cscript adplus.vbs -hang -pn %1 -quiet

goto :EOF

:Usage
echo Usage:
echo   %0 ProcessName EventNumber Logfile
echo       Logfile is optional.  If used, the eventlog name
echo       file ie, applicaiton, system, security, etc...

So, for example:

I've put the two files in my Debugging Tools for Windows installation directory, and can use them with:

DUMPONEL w3wp.exe 2023

DumpOnEL runs EvtMon with the second and third arguments. When Evtmon returns (Evtmon just waits for the event it's looking for, a bit like a conditional "pause" command), ADPlus runs and hang dumps everything with the first argument (process name) specified.

The process then continues running happily* after it's finished being dumped, and the file ends up in a Hang_Mode_xxxxx folder under the current directory.