1

I am looking for a way to close a window by class name. Since the Process class does not have something like GetProcessByClassName, I searched for a way to do this using the Win32 API. I have written the following code:

public partial class Form1 : Form
{
    [DllImport("user32", CharSet = CharSet.Unicode)]
    public static extern
    IntPtr FindWindow(string lpClassName,string lpWindowName);

    [DllImport("kernel32", CharSet = CharSet.Auto,SetLastError = true)]
    public static extern
    bool CloseHandle(IntPtr handle);

    private void button1_Click(object sender, EventArgs e)
    {
        IntPtr handle = FindWindow("Notepad", null);

        if (handle != IntPtr.Zero)
        {
           bool hresult = CloseHandle(handle);
        }
        else
        {
            MessageBox.Show("app is not running..");
        }
    }
}

However, when I do CloseHandle(), it gives the following error:

SEHEExeption was unhandle:External component has thrown an exception.

I have no idea of how to fix this.

halfer
  • 19,824
  • 17
  • 99
  • 186
Jack
  • 16,276
  • 55
  • 159
  • 284
  • 1
    what are you trying to achieve? btw FindWindow returns window handle (HWND) which is not a kernel object so it cannot be closed with CloseHandle() – alexm Dec 31 '11 at 20:26
  • possible duplicate of [Why can I not close the window handle in my code?](http://stackoverflow.com/questions/8507307/why-can-i-not-close-the-window-handle-in-my-code) – Deanna Dec 31 '11 at 22:12
  • 1
    [An hWnd is not a handle you can close with `CloseHandle()`](http://stackoverflow.com/questions/8507307/why-can-i-not-close-the-window-handle-in-my-code). Post the `WM_CLOSE` message instead. – Deanna Dec 31 '11 at 22:13
  • possible duplicate of [How to automate response to msgbox](http://stackoverflow.com/questions/2659708/how-to-automate-response-to-msgbox) – Hans Passant Dec 31 '11 at 23:17

2 Answers2

2

I don't believe that you need to close the handle opened from FindWindow.

However, depending on your needs, you may be better off using the .Net framework equivalent, GetProcessesByName:

var processes = System.Diagnostics.Process.GetProcessesByName("notepad");

foreach (System.Diagnostics.Process process in processes)
{
    // The main window handle can now be accessed 
    // through process.MainWindowHandle;
}
competent_tech
  • 44,465
  • 11
  • 90
  • 113
2

I found the solution finally. Thanks very much for @competent_tech and @Alexm,@Deanna,@Hans passant that helped me alot with your comments!

using System.Runtime.InteropServices;

    // ... 
       public class MyWindowHandling {

       private const int WM_CLOSE = 0x0010;

       [DllImport("user32", CharSet = CharSet.Unicode)]
        private static extern
        IntPtr FindWindow(
                string lpClassName,
                string lpWindowName
        );

       [DllImport("user32")]
        private static extern
        IntPtr SendMessage(
                IntPtr handle,
                int Msg,
                IntPtr wParam,
                IntPtr lParam
         );

         public void CloseWindowByClassName(string className) {
             IntPtr handle = FindWindow(null, className);
              if (handle != IntPtr.Zero) {
                   SendMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
               }
        }
      }
Community
  • 1
  • 1
Jack
  • 16,276
  • 55
  • 159
  • 284
  • One question here. I need to close an M.S Word window that holds a document. How do I signal discard or save the unsaved changes automatically using this method? Is that possible? – Nadeem Ullah Aug 05 '13 at 10:12