CloseHandle()给出了一个异常:外部组件抛出异常

时间:2011-12-31 20:12:39

标签: c# .net winapi

我正在寻找一种按类名关闭窗口的方法。由于Process类没有类似GetProcessByClassName的东西,我使用Win32 API搜索了一种方法。我写了以下代码:

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..");
        }
    }
}

但是,当我执行CloseHandle()时,它会出现以下错误:

  

SEHEExeption无法处理:外部组件抛出异常。

我不知道如何解决这个问题。

2 个答案:

答案 0 :(得分:2)

我不相信您需要关闭从FindWindow打开的句柄。

但是,根据您的需要,您可能最好使用等效的.Net框架,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;
}

答案 1 :(得分:2)

我终于找到了解决方案。非常感谢@competent_tech@Alexm@Deanna@Hans passant,这些都帮助了我的评论!

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);
               }
        }
      }