Программное нажатие на кнопку окна сторонней программы - C#
Формулировка задачи:
У себя в коде запускаю 3dsMax (через Process.Start()) на выполнение скрипта, в процессе работы всплывает предупреждение в виде MessageBox с кнопкой ОК, нажатие на которую продолжает работу скрипта. По завершению работы скрипт закрывает 3dsMax и дальше выполняется мой код, ибо WaitForExit(). Кнопка OK у окна с предупреждением имеет фокус по умолчанию и закрывается при нажатии на Enter. На данный момент для автоматического пропуска окна с предупреждением я использую подручный предмет для зажатия кнопки на клавиатуре. Более лаконичным решением я вижу создание и запуск нового потока непосредственно перед запуском 3dsMax.exe в котором будет отслеживаться окно с заголовком "Degenerate Faces" и если такое есть "кликать" кнопку ОК. По завершении работы процесса, завершается этот поток.
Вопрос, как найти нужное мне окно и нажать на ОК программно? Будет ли это работать на отдельном виртуальном рабочем столе в Windows 10, чтобы я параллельно мог работать на другом?
Решение задачи: «Программное нажатие на кнопку окна сторонней программы»
textual
Листинг программы
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
const uint WM_CLOSE = 0x0010;
public void Run()
{
bool export = maxScriptFileName.EndsWith("Export.ms");
string arguments = $"-q {(export ? "-ma" : "-mi")} -U MAXScript {maxScriptFileName}";
WriteLine($">>> Run 3dsMax to executing '{maxScriptFileName}' script in {(export ? "maximized" : "minimized")} mode . . .");
if (export)
{
var thread = new Thread(CloseDegenrateFacesWindow);
thread.Start();
Process.Start(maxExeFileName, arguments).WaitForExit();
thread.Abort();
}
else
Process.Start(maxExeFileName, arguments).WaitForExit();
}
private void CloseDegenrateFacesWindow()
{
while (true)
{
IntPtr hWnd = FindWindow(null, "Degenerate Faces");
if (hWnd != IntPtr.Zero)
SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
Thread.Sleep(100);
}
}