简体   繁体   中英

taskkill to differentiate 2 images by path

How to kill a process by name and orginiated from a particular path using taskkill?

taskkill /F /IM

certainly it cant differentiate 2 process started from two different locations C:\\Dir1 and C:\\Dir2

Does tasklist has any switch to get the path name

taskkill cannot do it. But you could use PowerShell if it's an option:

(Get-WmiObject Win32_Process | Where-Object { $_.Path.StartsWith('C:\Dir1') }).Terminate()

Based on Joey's answer:

wmic Path win32_process Where "CommandLine Like '%C:\\Dir1\\image.exe%'" Call Terminate

This way I avoid NullReferenceException when Path is null (don't know why) and does not need PowerShell.

Ref: https://superuser.com/questions/52159/kill-a-process-with-a-specific-command-line-from-command-line


Warning

It is dangerous if there are other processes running with the commandline contains that image path. For example:

> start cmd /k "C:\windows\system32\notepad.exe"

> wmic Path win32_process where "CommandLine Like '%C:\\Windows\\system32\\notepad.exe%'" get caption,processid,executablePath,commandline
Caption      CommandLine                                ExecutablePath                   ProcessId
cmd.exe      cmd  /k "C:\windows\system32\notepad.exe"  C:\WINDOWS\system32\cmd.exe      11384
notepad.exe  C:\windows\system32\notepad.exe            C:\windows\system32\notepad.exe  9684

So... What if we use "C:\\Dir1\\image.exe%" instead of "%C:\\Dir1\\image.exe%"?

If we launched this program from Explorer, its commandline may be quoted. If we ignore it, there will be no matches:

> wmic Path win32_process where "CommandLine Like '%C:\\Windows\\system32\\notepad.exe%'" get caption,processid,executablePath,commandline
Caption      CommandLine                                ExecutablePath                   ProcessId
notepad.exe  "C:\WINDOWS\system32\notepad.exe"          C:\WINDOWS\system32\notepad.exe  108

> wmic Path win32_process where "CommandLine Like 'C:\\Windows\\system32\\notepad.exe%'" get caption,processid,executablePath,commandline
No Instance(s) Available.

Therefore, it is recommended to use "ExecutablePath" like l0pan's answer .

Use the following command (it works even without powershell):

wmic process where ExecutablePath='C:\\Dir1\\image.exe' delete

NOTE: ExecutablePath is accessable for all processes only if you run wmic as administrator on Windows 8

Your case seems to be when you have custom services with same process name installed on the machine from different paths. If this is indeed the scenario, you probably have different Service Names which can be used as an additional filter.

See Syntax:

taskkill /S {REPLACE_WITH_SERVER_IP_OR_NAME} /F /FI "IMAGENAME eq {REPLACE_WITH_PROCESS_NAME}" /FI "SERVICES eq {REPLACE_WITH_SERVICENAME}"

See Example:

taskkill /S 10.10.1.1 /F /FI "IMAGENAME eq tomcat7.exe" /FI "SERVICES eq tomcatServiceEngine"

For list of all available filters, please visit taskkill command

You can only find your processes' path unless you are running powershell with administrator privilege.


32-bit PowerShell cannot find the path of 64-bit process via Get-Process , so I suggest you use WMI or CIM. Some references that may be useful:


PowerShell way. Based on Joey's answer and user's comment .

Assuming that the path of the program is C:\\Dir1\\file.exe . If multiple instances of the program are running, you should use the following command:

Get-WmiObject Win32_Process |
    Where-Object { $_.Path -eq "C:\Dir1\file.exe" } |
        ForEach-Object { $_.Terminate() }

Otherwise, Powershell will report an error:

PS > (Get-WmiObject Win32_Process |
    Where-Object { $_.Path -eq "C:\Dir1\file.exe" }).Terminate()

Method invocation failed because [System.Object[]] doesn't contain a method named 'Terminate'.

In addition, the above command also avoids the error when no matching process is found (eg, the Path of no process is equal to C:\\Dir1\\file.exe ):

PS > (Get-WmiObject Win32_Process |
    Where-Object { $_.Path -eq "C:\Dir1\file.exe" }).Terminate()

You cannot call a method on a null-valued expression.

If you don't like WMI:

Get-Process |
    Where-Object { $_.Path -eq "C:\Dir1\file.exe" } |
        ForEach-Object { Stop-Process -Id $_.Id }

I noticed that both Win32_Process.Terminate() and Stop-Process are used to forcibly terminate the process, so the process may not be able to perform any cleanup work.

Tested in Powershell 2.0 on Windows 7 (6.1.7600.0).


If you do like WMI and you are on Windows 6.2 (Windows server 2012 and Windows 8) and later, you should use Get-CimInstance instead of Get-WmiObject in PowerShell 3 and later ( Introduction to CIM Cmdlets | PowerShell Team ):

Get-CimInstance Win32_Process |
    Where-Object { $_.Path -eq "C:\Dir1\file.exe" } |
        Invoke-CimMethod -MethodName "Terminate"

Or, more CIM'y:

Get-CimInstance CIM_Process |
    Where-Object { $_.Path -eq "C:\Dir1\file.exe" } |
        Invoke-CimMethod -MethodName "Terminate"

Here, you may want to know why Invoke-CimMethod :

And, why "CIM":

I didn't test it on Windows 6.2, but Windows 10 (10.0.19041.0).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM