Using Taskkill.exe to Kill Multiple Processes on One Line

I’ve had an issue with my current App-V 5 application.  When I launch an executable called CentralSurveillance.exe, it spawns another two processes called K2DataLogger.exe and K2MSService.exe.  And these remain open even when I close CentralSurveillance.exe.  My first thoughts were that these were child processes, so I added the following to the DeploymentConfig:

<TerminateChildProcesses>
<Application Path="[{ProgramFilesX86}]\K2 Medical Systems\Guardian\CentralSurveillance.exe" />
</TerminateChildProcesses>

Sure enough, when I closed the instance of CentralSurveillance.exe….the instances of K2DataLogger.exe and K2MSService.exe were still running!  So I dug a little deeper – were these actually child processes or not?

I opened up a command prompt and ran:

wmic process Get Name,Description,CommandLine,ProcessId,ParentProcessId /format:list > processes.txt

What this does is list the name, description, command line, process id and parent process id of each running process and outputs it to a text file called processes.txt.  The results (after I’d deleted the irrelevant stuff) were as follows:

CommandLine="C:\Program Files\Microsoft Application Virtualization\Client\AppVClient.exe"
Description=AppVClient.exe
Name=AppVClient.exe
ParentProcessId=496
ProcessId=2664

CommandLine=C:\windows\system32\svchost.exe -k DcomLaunch
Description=svchost.exe
Name=svchost.exe
ParentProcessId=496
ProcessId=612

CommandLine=C:\windows\Explorer.EXE
Description=explorer.exe
Name=explorer.exe
ParentProcessId=4032
ProcessId=4224

CommandLine="C:\Users\xxxxx\AppData\Local\Microsoft\AppV\Client\Integration\07390066-7746-41A4-B6FB-3D1977D289BA\Root\VFS\ProgramFilesX86\K2 Medical Systems\Guardian\CentralSurveillance.exe"
Description=CentralSurveillance.exe
Name=CentralSurveillance.exe
ParentProcessId=4224
ProcessId=6120

CommandLine="C:\ProgramData\App-V\07390066-7746-41A4-B6FB-3D1977D289BA\CF8C5523-5038-4C73-991E-EBB4812B110B\Root\VFS\ProgramFilesX86\K2 Medical Systems\Guardian\K2DataLogger.exe"
Description=K2DataLogger.exe
Name=K2DataLogger.exe
ParentProcessId=2664
ProcessId=6040

CommandLine="C:\ProgramData\App-V\07390066-7746-41A4-B6FB-3D1977D289BA\CF8C5523-5038-4C73-991E-EBB4812B110B\Root\VFS\ProgramFilesX86\K2 Medical Systems\Guardian\K2MSService.exe"
Description=K2MSService.exe
Name=K2MSService.exe
ParentProcessId=2664
ProcessId=3872

We can clearly see that the parent process of K2DataLogger.exe and K2MSService.exe is NOT CentralSurveillance.exe (process id 6120) but instead AppVClient.exe (process id 2664).  And this is probably why TerminateChildProcesses will not work in this instance.  The workaround I used is to run an ExitProcess script so that when we close CentralSurveillance.exe, it kills both K2DataLogger.exe and K2MSService.exe.

I did this like so:

<UserScripts>
<ExitProcess>
<Path>CMD.EXE</Path>
<Arguments>/C taskkill /im "K2DataLogger.exe" /f /t &amp; taskkill /im "K2MSService.exe" /f /t</Arguments>
<Wait RollbackOnError="false" />
<ApplicationId>[{ProgramFilesX86}]\K2 Medical Systems\Guardian\CentralSurveillance.exe</ApplicationId>
</ExitProcess>
</UserScripts>

You can see that I can specify multiple command lines to run via CMD.exe by separating each command by an ampersand (& – this needs to be URL encoded in an XML file which is why it would appear as &amp; instead).  In the workaround above I specify two processes.  However by using brackets and nesting commands, I can specify more!  Here’s an example of an argument that kills 4 processes:

taskkill /im "odbcad32.exe" /f /t & (taskkill /im "wordpad.exe" /f /t & (taskkill /im "notepad.exe" /f /t & taskkill /im "mspaint.exe" /f /t))