CloseHandle () дает исключение: внешний компонент выдал исключение - PullRequest
1 голос
/ 01 января 2012

Я ищу способ закрыть окно по имени класса. Поскольку у класса 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 ]

2 голосов
/ 01 января 2012

Я наконец нашел решение. Большое спасибо за @ компетентный_тех и @ Алексм , @ Дина , @ Ганс Пассант , которые мне очень помогли с вашими комментариями!

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);
               }
        }
      }
2 голосов
/ 01 января 2012

Я не верю, что вам нужно закрывать дескриптор, открытый из FindWindow.

Однако, в зависимости от ваших потребностей, вам лучше использовать эквивалентный .NET Framework, 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...