views:

733

answers:

6
+2  Q: 

C# Process Killing

i need to write a program in c# that would just start, kill one process\exe that it is supposed to kill and enditslef.

The process i need to kill is another C# application so it is a local user process and i know the path to the exe

HOW TO DO IT... F1! F1!

+1  A: 

You can achieve it by using Process Class class but why would you want to kill another process?

Giorgi
+1  A: 

Process class has Kill() method

Anton Setiawan
+1  A: 

you can call the Process.Kill method

you can use the Process.GetProcesses to get all processes or Process.GetProcessByName or Process.GetProcessById so you can get the process to call Kill on.

Sam Holder
+9  A: 

Check out Process.GetProcessesByName and Process.Kill

        // Get all instances of Notepad running on the local
        // computer.
        Process [] localByName = Process.GetProcessesByName("notepad");
        foreach(Process p in localByName)
        {
           p.Kill();
        }
SwDevMan81
+3  A: 

First search all processes for the process you want to kill, than kill it.

Process[] runningProcesses = Process.GetProcesses();
foreach (Process process in runningProcesses)
{
    // now check the modules of the process
    foreach (ProcessModule module in process.Modules)
    {
        if (module.FileName.Equals("MyProcess.exe"))
        {
            process.Kill();
        }
    }
}
Simon Linder
If you know already the process name there is no need to loop all processes. See the answer posted by @SwDevMan81.
0xA3
It is said that he knows the path of the exe not the name of the process. Otherwise your are absolutely right.
Simon Linder
And even if you know the name, what if more than one instance is running? Or what if two different programs have the same name?
Chris Dunaway
+4  A: 

Killing processes by their name can be easily done in C# (as the other answers already showed perfectly). If you however want to kill processes based on the full path of the executable things get more tricky. One way to do that would be to use WMI, another way would be to use the Module32First Windows API function.

The sample below uses the latter approach. It first selects a subset of the running processes by their name and then queries each of these processes for their full executable path. Note that this path will be the actual path of the image being executed, which is not necessarily the executable that was launched (e.g. on x64 systems the actual path to calc.exe will be C:\Windows\SysWOW64\calc.exe even if the file C:\Windows\system32\calc.exe was started). All processes with a matching path are returned by GetProcessesByPath:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

class Program
{
    static void Main(string[] args)
    {
        Process[] processList = GetProcessesByPath(@"C:\Program Files\MyCalculator\calc.exe");
        foreach (var process in processList)
        {
            if (!process.HasExited)
                process.Kill();
        }
    }

    static Process[] GetProcessesByPath(string path)
    {
        List<Process> result = new List<Process>();

        string processName = Path.GetFileNameWithoutExtension(path);
        foreach (var process in Process.GetProcessesByName(processName))
        {
            ToolHelpHandle hModuleSnap = NativeMethods.CreateToolhelp32Snapshot(NativeMethods.SnapshotFlags.Module, (uint)process.Id);
            if (!hModuleSnap.IsInvalid)
            {
                NativeMethods.MODULEENTRY32 me32 = new NativeMethods.MODULEENTRY32();
                me32.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(me32);
                if (NativeMethods.Module32First(hModuleSnap, ref me32))
                {
                    if (me32.szExePath == path)
                    {
                        result.Add(process);
                    }
                }
                hModuleSnap.Close();
            }
        }

        return result.ToArray();
    }
}

//
// The safe handle class is used to safely encapsulate win32 handles below
//
public class ToolHelpHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private ToolHelpHandle()
        : base(true)
    {
    }

    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    protected override bool ReleaseHandle()
    {
        return NativeMethods.CloseHandle(handle);
    }
}
//
// The following p/invoke wrappers are used to get the list of process and modules
// running inside each process.
//
public class NativeMethods
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static public extern bool CloseHandle(IntPtr hHandle);

    [DllImport("kernel32.dll")]
    static public extern bool Module32First(ToolHelpHandle hSnapshot, ref MODULEENTRY32 lpme);

    [DllImport("kernel32.dll")]
    static public extern bool Module32Next(ToolHelpHandle hSnapshot, ref MODULEENTRY32 lpme);

    [DllImport("kernel32.dll")]
    static public extern bool Process32First(ToolHelpHandle hSnapshot, ref PROCESSENTRY32 lppe);

    [DllImport("kernel32.dll")]
    static public extern bool Process32Next(ToolHelpHandle hSnapshot, ref PROCESSENTRY32 lppe);

    [DllImport("kernel32.dll", SetLastError = true)]
    static public extern ToolHelpHandle CreateToolhelp32Snapshot(SnapshotFlags dwFlags, uint th32ProcessID);

    public const short INVALID_HANDLE_VALUE = -1;

    [Flags]
    public enum SnapshotFlags : uint
    {
        HeapList = 0x00000001,
        Process = 0x00000002,
        Thread = 0x00000004,
        Module = 0x00000008,
        Module32 = 0x00000010,
        Inherit = 0x80000000,
        All = 0x0000001F
    }

    [StructLayoutAttribute(LayoutKind.Sequential)]
    public struct PROCESSENTRY32
    {
        public uint dwSize;
        public uint cntUsage;
        public uint th32ProcessID;
        public IntPtr th32DefaultHeapID;
        public uint th32ModuleID;
        public uint cntThreads;
        public uint th32ParentProcessID;
        public int pcPriClassBase;
        public uint dwFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szExeFile;
    };

    [StructLayoutAttribute(LayoutKind.Sequential)]
    public struct MODULEENTRY32
    {
        public uint dwSize;
        public uint th32ModuleID;
        public uint th32ProcessID;
        public uint GlblcntUsage;
        public uint ProccntUsage;
        IntPtr modBaseAddr;
        public uint modBaseSize;
        IntPtr hModule;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szModule;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szExePath;
    };
}

Some of the code is based on an article by Jason Zander which can be found here.

0xA3