Я хочу закрыть окно с каким-то именем (любое приложение, например, калькулятор и т.д.). Как это сделать на С#? Импортировать функции 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 может быть чем-то приемлемым и чистое закрытие для прямого отклонения. В последнем случае у вас действительно нет выбора. Это не ваш процесс. Между вами, как вы видели, могут быть какие-то промежуточные окна, диалоговые окна и т.д., С которыми вам придется бороться.
Итак, что вы пытаетесь достичь здесь? Почему вы пытаетесь закрыть окна, принадлежащие другим процессам? Это может помочь прояснить, какова цель.