Как закрыть окно по его названию?

Я хочу закрыть окно с каким-то именем (любое приложение, например, калькулятор и т.д.). Как это сделать на С#? Импортировать функции WinAPI?

Ответ 1

Да, вы должны импортировать функции Windows API: FindWindow(), SendMessage(); и WM_CLOSE константа.

Основные определения функций Windows API:

[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;

Клиентский код:

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

Ответ 2

Вы пытаетесь закрыть окна, принадлежащие другим процессам. Это не то, что вы можете предположить, будет надежно. Во-первых, ВЫ НЕ владеете этими окнами, поэтому у ВАС нет действительно автоматического права идти и возиться с окнами других процессов.

Как следует из другого ответа, вы можете попробовать отправить WM_CLOSE в окно, но он содержит предостережение о том, что другой процесс на самом деле не имеет права его соблюдать. Ответ на WM_CLOSE может быть чем-то приемлемым и чистое закрытие для прямого отклонения. В последнем случае у вас действительно нет выбора. Это не ваш процесс. Между вами, как вы видели, могут быть какие-то промежуточные окна, диалоговые окна и т.д., С которыми вам придется бороться.

Итак, что вы пытаетесь достичь здесь? Почему вы пытаетесь закрыть окна, принадлежащие другим процессам? Это может помочь прояснить, какова цель.