0

I am looking to automate the execution of a .bat file every time I open a specific application, such as notepad.exe, on Windows 10. Here is what I have done so far:

  1. I configured the local security policy to log application starts and stops (Audit process tracking -> Success). This generates an entry in the security event log each time a process starts or ends.

  2. I set up a scheduled task to trigger "on an event." Below is the XML code for the event filter I'm using:

    <QueryList>
      <Query Id="0" Path="Security">
        <Select Path="Security">
          *[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task =
          13312 and (band(Keywords,9007199254740992)) and (EventID=4688)]] and
          *[EventData[Data[@Name='ProcessName'] and
          (Data='C:\Windows\System32\notepad.exe')]]
        </Select>
      </Query>
    </QueryList>
    
  3. In the action tab of the scheduled task, I configured it to run the desired .bat file.

However, the scheduled task only triggers the first time I open notepad. I need it to run every time I start notepad.exe. How can I do to trigger the task every time I run notepad.exe?

1
  • You could try an alternative method. Create a batch file called notepad_start.bat, place whatever you need executing before running notepad, and run notepad from the batch file by using C:\Program Files\WindowsApps\Microsoft.WindowsNotepad_11.2401.26.0_x64__8wekyb3d8bbwe\Notepad\Notepad.exe Commented Apr 25 at 6:59

1 Answer 1

0

I was able to get this working with a specific scheduled task setting and a slightly modified query.

Settings

The scheduled task setting that might be causing the subsequent execution problem you're facing is If the task is already running, then the following rule applies in the Settings tab of the task. This defaults to "Do not start a new instance," which might be blocking your .bat file from running if the previous instance has not exited yet. If your .bat file is long-running, you may want to change this setting to "Run a new instance in parallel" or "Stop the existing instance."

Filter

<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">
      *[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4688)] and
        EventData[Data[@Name='NewProcessName'] = 'C:\Windows\system32\notepad.exe']]
    </Select>
  </Query>
</QueryList>

I made the selector match Data elements where the same Data instance which has the Name attribute set to ProcessName also has its own text value set to C:\Windows\system32\notepad.exe, instead of allowing different Data elements to fulfill the attribute and value matches, in order to avoid false positives. I removed some other selectors for brevity but they shouldn't affect the correctness. Overall, this doesn't seem like it would have caused the subsequent execution problem you're asking about, but this query is what I tested with on my computer.

Unfortunately, Event Log XPath 1.0 queries don't have the lower-case(), contains(), substring(), or ends-with() functions, so the absolute path to notepad.exe is not as easy to match in all situations as it should be. This gets more tricky with the UWP/AppX version of Notepad that has a version number in its installation directory. Solutions that need more flexibility consume the Event Log records in a separate background process with custom logic.

Exported task XML

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2024-04-24T23:37:11.8710167</Date>
    <Author>AEGIR\Ben</Author>
    <URI>\Ben\On Notepad Launched</URI>
  </RegistrationInfo>
  <Triggers>
    <EventTrigger>
      <Enabled>true</Enabled>
      <Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="Security"&gt;&lt;Select Path="Security"&gt;*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4688)] and EventData[Data[@Name='NewProcessName'] = 'C:\Windows\system32\notepad.exe']]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription>
    </EventTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-21-1767694704-3563880056-2304008930-1001</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>StopExisting</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>winver.exe</Command>
    </Exec>
  </Actions>
</Task>
2
  • I have another question. Would there be any performance penalty associated with process tracking? I fired up Event Viewer on my laptop and saw 16,000 events in the Windows Security Log after seven hours of normal usage.
    – nehalchoy
    Commented Apr 25 at 12:27
  • Like most performance analysis it's subjective and situation-specific. Starting a new console host process isn't free, but it may not be noticeable underneath a certain frequency, especially as the CPU speed and core count increase. In the spirit of avoiding premature optimization, I would probably go with the scheduled task batch approach until it became a problem. Then I'd switch to a permanently resident background process that starts once and subscribes to Event Log, for example in a C# Windows service that uses System.Diagnostics.Eventing.Reader.EventLogWatcher. Commented Apr 25 at 22:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .