19

I want to close window with some name (any application, for example, calculator and etc.). How to do it in C#? Import WinAPI functions?

Artem Tsarionov
  • 329
  • 1
  • 2
  • 6
  • 3
    http://www.codeproject.com/Articles/22257/Find-and-Close-the-Window-using-Win-API ... google rox you know – m0s Feb 12 '12 at 11:40
  • Possible duplicate. http://stackoverflow.com/questions/116090/how-do-i-kill-a-process-using-vb-net-or-c – Lloyd Feb 12 '12 at 11:40
  • @Lloyd: Not a duplicate, killing a process is not the same thing as closing a window. – Cody Gray - on strike Feb 12 '12 at 12:00
  • @CodyGray I took the belief that the user was talking about a process due to his reference to "any application". – Lloyd Feb 12 '12 at 12:02

2 Answers2

33

Yes, you should import the Windows API functions: FindWindow(), SendMessage(); and WM_CLOSE constant.

Native definitions of the Windows API functions:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

/// <summary>
/// Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.
/// </summary>
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

const UInt32 WM_CLOSE = 0x0010;

Client code:

IntPtr windowPtr = FindWindowByCaption(IntPtr.Zero, "Untitled - Notepad");
if (windowPtr == IntPtr.Zero)
{
    Console.WriteLine("Window not found");
    return;
}

SendMessage(windowPtr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
  • 1
    Yes, this works just fine for Notepad (assuming, of course, that the window title is exactly what you've given here, which it probably isn't most of the time). But it won't work for applications that have multiple top-level windows, unless they've been specifically designed to close the entire app after the closing of a single top-level window. Otherwise, you need to send `WM_CLOSE` to *each* of the top-level windows to ensure that the app gets closed. – Cody Gray - on strike Feb 12 '12 at 11:57
  • 1
    Additionally, apps can choose to respond to `WM_CLOSE` however they like. For example, some programs choose to minimize themselves to the taskbar's notification area upon receipt of this message, rather than actually close. Since you can't control how the application responds to the message, you need to test this method extensively and realize how potentially fragile it is when dealing with unknown and untested applications. – Cody Gray - on strike Feb 12 '12 at 11:57
  • @Artem: No. Did you read [the documentation](http://msdn.microsoft.com/en-us/library/windows/desktop/ms632678.aspx) for the `CloseWindow` function? It *minimizes* the specified window, i.e. to the taskbar. – Cody Gray - on strike Feb 12 '12 at 12:48
  • @CodyGray, the question is how to close the *window*, not how to close that application. This answer seems to be exactly what is being asked for. – svick Feb 12 '12 at 13:26
  • 1
    @svick: I wasn't disagreeing, in fact I upvoted the answer. But the question is not entirely clear. I was just clarifying important caveats. – Cody Gray - on strike Feb 12 '12 at 13:28
  • 1
    Note that even for notepad, you'll get a "Do You Want To Save Changes to ... ?" dialog if the content has been changed since last save - and similarly with many other apps, each of which may have a different style of confirmation dialog. Also, be careful with SendMessage: in some apps, it may block until the confirmation dialog is dealt with - eg. if the target app calls MessageBox within its WM_CLOSE handler; PostMessage might be a safer best if you don't want to block. – BrendanMcK Feb 12 '12 at 23:45
-1

You're trying to close windows belonging to other processes. That isn't something you can assume will go reliably. For one thing, YOU don't own those windows so YOU don't really have any automatic entitlement to go and mess with the other processes' windows.

As the other answer suggests, you can try sending a WM_CLOSE to the window but it comes with the caveat that the other process isn't really entitled to honour it. The response to WM_CLOSE can be anything to acceptance and a clean shutdown to outright rejection. In the latter case, you've really got no option. It's not your process. In between, as you've seen, there could be any sort of intermediate windows, dialog boxes, etc, that you'd have to contend with.

So what are you trying to achieve here? Why are you trying to close windows belonging to other processes? It might help to clarify what the aim is.

Steven Palmer
  • 300
  • 2
  • 12