See Microsoft KB Archive/178893. It is an old Microsoft Knowledge Base article. The C++ code does not help but the concepts are still valid. The important thing is that it says to first try sending a WM_CLOSE message. The Process.CloseMainWindow Method will do that; close the process "cleanly". Kill should be used only if it is not possible to close the process cleanly.
And if you want to do a more efficient search then the following might help. It is more code for you but it will enumerate the desktop windows and get the process for each.
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll", EntryPoint = "EnumDesktopWindows",
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool EnumDesktopWindows(IntPtr hDesktop,
EnumDelegate lpEnumCallbackFunction, IntPtr lParam);
private delegate bool EnumDelegate(IntPtr hWnd, IntPtr lParam);
public static SortedSet<uint> EnumWindows()
var ProcessList = new SortedSet<uint>();
EnumDelegate callBackFn = new EnumDelegate(EnumProc);
GCHandle handle1 = GCHandle.Alloc(ProcessList);
EnumDesktopWindows(IntPtr.Zero, callBackFn, (IntPtr)handle1);
return ProcessList;
public static bool EnumProc(IntPtr hwnd, IntPtr lparam)
uint processId = 0;
GCHandle handle2 = (GCHandle)lparam;
uint threadId = GetWindowThreadProcessId(hwnd, out processId);
SortedSet<uint> ProcessList = (handle2.Target as SortedSet<uint>);
if (!ProcessList.Contains(processId))
ProcessList.Add(processId);
return true;
static void Main(string[] args)
SortedSet<uint> ProcessList = EnumWindows();
foreach (uint processId in ProcessList)
Process ownerProcess = Process.GetProcessById((int)processId);
Console.WriteLine(ownerProcess.ProcessName);
I do not know how the .Net Process.GetProcessesByName
method finds the processes but I assume it uses something like in Enumerating All Processes so that even if you request a specific process by name, the method will first get all the processes. So requesting a process by name is not likely to save computer time; it just saves your programming time.
@Sam of Simple Samples makes some very good points. Even Windows Task Manager attempts to close a process in an orderly fashion before resorting to TerminateProcess. See https://devblogs.microsoft.com/oldnewthing/20040722-00/?p=102304. The Process.Kill method uses TerminateProcess and if called on a process other than your own can result in unanticipated and unexpected problems. For example, refer to the discussion at crash-during-terminateprocess