Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Как определить завершение внешней программы?


Автор: ZVano 1.4.2011, 13:03
Из программы А вызываю программу Б.
Программа Б в свою очередь может вызвать программы С1, С2, Сn и завершить свою работу не дожидаясь завершения порожденных процессов.

Вопрос: Как в программе А определить, что все процессы порожденные программой Б завершили свою работу?

Приатачиваю исходник программы(Программа А), которая демонстрирует данный процесс.
В папке \RUN\ лежат bat-файлы, которые вызываются разными методами из программы А.
Некоторые батники в свою очередь вызывают дочерние программы.
DoPause.bat - батник ничего из себя не вызывает. Просто висит, пока не закроеш. Его завершение отлавливается корректно.
CallCalc.bat - вызывает калькулятор и ждет его завершения. Отрабатывается корректно.
StartDoPause.bat - вызывает "DoPause.bat" и не дожидаясь его выполнения передает управление программе А. !!!Этот случай нужно обработать.
StartCalc.bat - вызывает калькулятор и не дожидаясь его выполнения передает управление программе А. !!!Этот случай нужно обработать.


Помогите, плиз. Голова уже разламывается.

Добавлено через 7 минут и 13 секунд
Этот кусок кода не подходит т.к. отслеживается завершение процесса Б, но не учитываются процессы порожденные от Б.
Код

LogAddLine("CreateProcessW::Beg");
STARTUPINFOW startupInfo;
PROCESS_INFORMATION processInfo;
GetStartupInfoW(&startupInfo);
UnicodeString fPathW = "C:\\WINDOWS\\system32\\calc.exe"

bool runResult = CreateProcessW( //
  NULL //
  , fPathW.w_str() //
  , NULL //
  , NULL //
  , false //
  , NULL //
  , NULL //
  , NULL //
  , &startupInfo //
  , &processInfo //
  ) == true;

if (!runResult) {
  LogAddLine("Не получилось запустить процесс");
  return;
}
LogAddLine( //
  UnicodeString::Format("Информация процесса: hProcess=<%d> hThread=<%d> dwProcessId=<%d> dwThreadId=<%d>", //
    OPENARRAY( //
      TVarRec, ( //
        (int)processInfo.hProcess //
        , (int)processInfo.hThread //
        , processInfo.dwProcessId //
        , processInfo.dwThreadId //
      ) //
    ) //
  ) //
  );
while (true) {
  DWORD exitCode = 0;
  if (!GetExitCodeProcess(processInfo.hProcess, &exitCode)) {
    // if (!GetExitCodeThread(processInfo.hThread, &exitCode))
    LogAddLine("Не получилось обратиться к процессу");
    break;
  }
  if (exitCode != STILL_ACTIVE) {
    LogAddLine("Умерло... выход");
    break;
  }
  else {
    LogAddLine("Живо... ожидаем");
    Application->ProcessMessages();
    Sleep(1000);
  }
}
LogAddLine("CreateProcessW::End");

Автор: ИванМ 13.4.2011, 09:31
Как вариант, пройтись по всем запущенным процессам с помощью CreateToolhelp32Snapshot, узнать, какие из них являются наледниками B и соотвественно с ними уже работать.

Автор: xvr 13.4.2011, 11:33
Цитата(ИванМ @ 13.4.2011,  09:31)
Как вариант, пройтись по всем запущенным процессам с помощью CreateToolhelp32Snapshot, узнать, какие из них являются наледниками B и соотвественно с ними уже работать.

Если В успел быстренько наплодить потомков и помереть, перед тем как начали звать CreateToolhelp32Snapshot, то уже ничего не узнаешь  smile Ситуация усложняется еще тем, что это может произойти в любой момент времени (и произойдет, т.к. сам В не ждет своих потомков, а значит есть большая вероятность, что он завершится сразу после создания последнего. А вероятность того, что вызов CreateToolhelp32Snapshot попадет в этот небольшой временной интервал, исчезающе мала  smile )

Автор: ZVano 15.4.2011, 15:56
Наткнулся на API IsChild, но не проверял на работоспособность т.к. другим шибко занят, а 1е задание сделал по-иному.

Функция IsChild
--------------------------------------------------------------------------------
Функция IsChild проверяет, является ли окно дочерним окном или порожденным окном заданного родительского окна. Дочернее окно - прямой потомок определяемого родительского окна, если это родительское окно находится в цепочке родительских окон; цепочка родительских окон управляет в диапазоне от оригинала перекрывающего или выскакивающего окна до дочернего окна.

Синтаксис
Код

BOOL IsChild( 

HWND hWndParent, // дескриптор родительского окна
HWND hWnd        // дескриптор окна для проверки

);

Параметры

hWndParent

[in] Дескриптор родительского окна.

hWnd

[in] Дескриптор окна, которое будет проверяться.

Возвращаемые значения

Если окно - дочернее или порожденное окно заданного родительского окна, возвращаемое значение не нуль.

Если окно - не дочернее или порожденное окно заданного родительского окна, возвращаемое значение нулевое.

Автор: xvr 15.4.2011, 19:29
Цитата(ZVano @  15.4.2011,  15:56 Найти цитируемый пост)
Функция IsChild проверяет, является ли окно дочерним окном или порожденным окном заданного родительского окна.

Угу, и к процессам она не имеет никакого отношения. Окно не может быть дочерним окном окна из другого процесса

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)