Apes Jaguar
Apes Jaguar

Reputation: 49

C# End Task not End Process

Another question here. I Just want to know if it is possible to End Task those Application using C#.

Like: there are 4 Notepad application opened. i just want to close the 2nd Notepad Application. but when i tried to use process.Kill, all 4 Notepad are being closed. is there any way to close only the specified Noteped?

Here is my sample Code:

foreach (Process p in Process.GetProcesses("."))
{
    if (p.MainWindowTitle.Length > 0)
    {
        if (p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt")
        {
            p.Kill();
        }
    }
}

Upvotes: 4

Views: 2547

Answers (4)

Andrei G
Andrei G

Reputation: 1590

First of all, I think you mean you only want to close the notepad process that is viewing the NotepadName.txt file. You are probably trying to deny access to the file (or close whoever is accessing it for whatever reason). Therefore I am ignoring "2nd" part.

I ran your code and tested it, and was able to close only the notepad process that was accessing the file I targeted.

However what I noticed is that your comparison is definitely not correct.

//not all processes have a string of 31 characters 
//so sometimes it will trigger an exception
if (p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt") 
    {
        p.Kill();
    }

For your purpose, replace with

if (p.MainWindowTitle.Contains("NotepadName.txt"))
    {
        p.Kill();
    }

From the tests I ran, this should work.

Upvotes: 0

penartur
penartur

Reputation: 9912

There's been a lot of messing up with PIDs, so i have to write a cleaner answer to the question everybody are answering to (although that might not be an original question).

So, in order to kill the second (in the order of process start time) process fullfilling the conditions in your example, you should write

var processToKill = (from p in Process.GetProcesses(".") where p.MainWindowTitle.Length > 0 and p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt" order by p.StartTime).Skip(1).FirstOrDefault();
if(processToKill != null)
{
    processToKill.Kill();
}

Upvotes: 0

Maciej
Maciej

Reputation: 7961

You need to use process start time to find second run Notepad.

Process[] processes = (from prc in Process.GetProcessesByName("notepad")
                       orderby prc.StartTime
                       select prc).ToArray();

if (processes.Count() > 1)
    processes[1].Kill();

Upvotes: 3

Sam Greenhalgh
Sam Greenhalgh

Reputation: 6136

You iterating across all processes in the foreach (Process p in Process.GetProcesses(".")) loop and killing any process with a title that begins "NotepadName.txt".

If you want to kill only the second instance you'll have to modify the logic in the loop to be more selective.

int i = 0;
foreach (Process p in Process.GetProcesses("."))
{
    if (p.MainWindowTitle.Length > 0)
    {
        if (p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt")
        {
            i++;
            if(i == 2){
                p.Kill();
                break;
            }
        }
    }
}

Upvotes: 0

Related Questions