windowspowershelleventswmiwmi-query

Schedule a task to monitor a certain process start


I'm trying to tie two applications together, so that when one is started the other starts too.

I expected to find this in Task Scheduler under Events > Application or something like that, but only some applications have event sources there.

So I researched and found that you can detect a process start by registering a WMI event.

Register-WMIEvent -Query "SELECT * FROM __InstanceCreationEvent WITHIN 3 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = 'notepad.exe'" -sourceIdentifier 'NotepadStarted' -action {if(!(ps AutoHotKey)) { start Automator.ahk}}

However this is meant to run all the time, which means a powershell.exe process in the background, and WMI polling every 3 seconds (WITHIN 3 - yes I do need it to respond ASAP). The PC is powerful enough for this job as is, but if in the future I want to watch more than one app, this approach may turn out to use too much resources.

Is there a better way of watching for a process start on Windows? Without polling or running a script continually in the background, but rather simply scheduling a task to respond to the event of Notepad having started?


Solution

  • I have found a way through Auditing, which seems to work alright. We're trying to get the process to raise an event when it starts, then in Task Scheduler to home in on that event as the trigger for our action.

    UPDATE: Conjoined Twins - IFTTT-style application actions using auditing and scheduled tasks under Windows. It's a Powershell script that helps you set this up.

    LATER EDIT: OK it does produce a few false positives. The action may fire without the program having actually been executed. So beware.

    Go to your application.exe, right click > Properties > Security tab > Advances > Auditing tab > Edit

    Add your username and tick Traverse folder / execute file. Click all of the OKs. Every successful execution of application.exe will now show up in Event Viewer. Go there to check them out:

    Event Viewer > Windows Logs > Security You can Filter current log for EventID 4663

    Here is an event like that from my machine:

    An attempt was made to access an object.

    Subject:
      Security ID:    PC\Redacted
      Account Name:   Redacted
      Account Domain:   PC
      Logon ID:   0xxxxxxx
    
    Object:
      Object Server:  Security
      Object Type:  File
      Object Name:  C:\Program Files\Some Application\application.exe
      Handle ID:  0x1e1c
    
    Process Information:
      Process ID: 0x374
      Process Name: C:\Windows\explorer.exe
    
    Access Request Information:
      Accesses: Execute/Traverse
    
      Access Mask:  0x20
    

    You'll see more than one of these, it's not just one-to-one, 1 program start = 1 event. There are A handle was open, A handle was closed events as well.
    In Task Scheduler you have to now create an event to target the program start.

    Create New Task > Triggers Tab > New

    Select Begin task: On an event from the drop-down.

    Click the Custom radio button then Edit Event Filter... button

    In the XML tab tick Edit query manually and paste something like this in:

    <QueryList>
      <Query Id="0" Path="Security">
        <Select Path="Security">*[EventData[Data[@Name='ObjectName'] and (Data='C:\Program Files\Some Application\application.exe')]]
      </Select>
      </Query>
    </QueryList>
    

    ¹
    Pictures and more details at Quick Development Tips: How to monitor a folder and trigger an action for incoming files, in Windows 7

    Once this is done, all that's left is to set up your Action, the program you want to run when application.exe starts. For me it was an AutoHotKey script - I just clicked Browse and navigated to it.

    Now when I start the app I get that AutoHotKey script automating some initial steps. It wouldn't have worked to just create a batch file with application.exe & script.ahk in it, because sometimes the app starts from opening a file, sometimes it's started by something else, or who knows. This way no matter how it starts, script.ahk happens.

    ¹ Side note: Here's a catch. This XPath query works for Data='C:\no\wildcards\allowed.exe' but you'll be disappointed to find that you can't use wildcards or any other kind of matching. So if you want to select a file that doesn't move or change name, that's fine. But if you want to select a newly created file of unknown name inside a folder you're watching - you can't. At most you can do Data='variant1' OR Data='variant2'...