Kill a process that use a certain image path - c#

I need to find a way to kill all processes that use a certain image path. I have been finding that killing the process by name doesn't always kill the process properly - due to the fact that its developers are unable to keep the same name from build to build.
I have done some digging around, but haven't been able to find a solution to this. Wondering if someone here can point me in the right direction.

Process.GetProcesses()
.First(p => String.Compare(p.MainModule.FileName,filename,true)==0)
.Kill();

this would kill all Processes that runs in the specific directory
System.Diagnostics.Process.GetProcesses()
.Where(p => Path.GetDirectoryName(p.MainModule.FileName).ToLower().Equals(path.ToLower())
.ToList().ForEach(p => p.Kill());

I believe this is what you want
var imagePath = #"C:\applicationfolder";
var processes = Process.GetProcesses()
.Where(p => p.MainModule.FileName.StartsWith(imagePath, true, CultureInfo.InvariantCulture));
foreach (var proc in processes)
{
proc.Kill();
}

Related

How to kill process by specific Id in c#

I have multiple processes that running at the same time of my C# program and all of this processes have the same name with different ID and I want to kill specific process of my program by their specific ID or rename them and kill it by their specific name.
Process.GetProcessById(Int32)
Process.Kill()
Edit:
Pay attention to Notes and Remarks sections of the documentation, specially for the Kill method.
If you have the id you can do it like this (where id is an int32):
Process process = Process.GetProcessById(id);
process.Kill();
Or if you are using LinQ you can do it like this:
Process.GetProcesses()
.Where(x => x.Id.Equals(id))
.FirstOrDefault()
.Kill();

How do I stop then start explorer.exe in C#?

So my computer has a lot of errors. 99% of the time, they're caused by explorer.exe being stupid. I can manually stop them, but I was thinking that I may be able to set up a schedule that automatically stops and starts it every 10 or so minutes, so I never have any problems with it any more. The code I have doesn't work, but I'll put it anyway:
foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
{
if (myProc.ProcessName == "explorer.exe")
{
myProc.Kill();
}
}
When I run it, absolutely nothing happens. Visual studio doesn't give an error, the program doesn't crash, etc. It just does nothing.
Please avoid use of the for-if anti-pattern:
var explorers = Process.GetProcessesByName("explorer");
foreach (var thisExplorer in explorers)
{
thisExplorer.Kill();
}
edit: as charmander noted in comments.
It's usually a good idea to look at the output of a partucular method/property before assuming you know what it contains.
In this case, myProc.ProcessName does not contain the extension of the process. So compare to "explorer".
Additionally, modifying a collection whilst foreaching over it usually results in a runtime error.
The process name is just "explorer"
EDIT:
This did the trick on my box:
foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
{
if (myProc.ProcessName == "explorer")
{
myProc.Kill();
}
}
You can do it the Linq way too
List<Process> processes = Process.GetProcesses().Where(p => p.ProcessName == "explorer").ToList();
foreach (var process in processes)
{
process.Kill();
}

Run more than 1 process in Process Class

Well, it will be a bit hard to explain what i need to do here, but it goes like this:
I am building a program that will need to run .exe (From different folders).
How can i do this, that i will be able to do Process.start(), but i will be able to kill it as well?
I mean, if I do:
System.Diagnostics.Process process;
process = process.start();
Then I can do Process.Kill(); but what if I dont know how many processes I have? How can I do more and more processes with the ability to kill them?
Is this even possible?
I am hoping i explained it correctly. I am not sure how I can explain it better :O
You can store the created processes in a list to track them. Remove them from the list when you kill them:
var list = new List<Process>();
var p1 = Process.Start(...);
list.Add(p1);
// similarly for other processes, or run this in a loop
// later...
var p = list[0];
p.Kill();
list.Remove(p);
// ...
You can also use other specialized collections (like a queue) if that makes more sense.

Different reference returned from Process.Start

ProcessStartInfo psi = new ProcessStartInfo(BatchFile)
Process p = Process.Start(psi)
Why p.ID is different than process id visible in WindowsTaskManager
(BatchFile is path to external program with appropriate parameters)
I would assume that it's because p.ID is the id of the process that's running the batch file rather than the id of the process started by the batch file.
You can start the executable directly by Process.Start by using the correct overload
I assume BatchFile is some kind of cmd or bat file that runs other processes one by one.
So in Windows Task Manager you actually see ids of those processes that are run by batch file.
Examples
If I do this
var p = Process.Start("notepad.exe");
p.Id will match to the PID from Task Manager.
However, if I do this:
var p = Process.Start("test.cmd"); // test.cmd has notepad.exe call inside
p.Id will be different from PID shown in the Task Manager.
A process ID is only meaningful while the process is alive. The first thing to check is .HasExited - if this is true, ignore the process ID; it no longer has any meaning.
There are a number of ways you can start something and have no process left even though you can apparently see it still on screen:
if it is a script/bat/cmd that spawns something and exits (remember: you are watching the script, not the "something")
if the exe does some inter-exe voodoo internally - for example, most of the office apps and internet explorer do this; if there is an existing process, it forwards the args to that process to handle, and exits immediately

Process Monitoring

I'm quite familiar with the System.Diagnostics.Process class. But, I'm wondering about how I can monitor a specific process (i.e. Check to see if it's running every XX mins/secs). I need to be able to checking whether a process is running and if it is, continue with initialising the rest of the program.
Thanks,
-Zack
Checking if it's still running is easy: Process.HasExited.
Rather than polling this periodically, however, you could set EnableRaisingEvents to true, and attach a handler to the Exited event.
EDIT: To answer the question in the comment about "fetching" the process - that depends on what you already know. If you know its process ID, you could use Process.GetProcessById. If you only know its name, you would have to use Process.GetProcessesByName and work out what to do if you get multiple results. If you don't know the exact name, you could use Process.GetProcesses and look for whatever you do know about it. Those options are effectively in order of preference :)
If you didn't start the process yourself, you get find the Process object associated with a process by looking through the list returned by Process.GetProcessesByName(...) or Process.GetProcesses(...)
Once you have the process, you can listen read its properties (including HasExited) and (as Jon mentions in his response) if you set EnableRaisingEvents you can listen to its events (including Exited).
Something like this, maybe?
Process[] processlist = Process.GetProcesses();
bool found = false;
foreach (Process theprocess in processlist)
{
if(theprocess.ProcessName == "YourProcessName")
{
found = true;
break;
}
}
if (!found)
{
return;
}

Categories

Resources