Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Ожидание завершения процесса


Автор: Irinka 6.9.2006, 08:38
Есть ярлык, запускающий процесс на удаленном сервере. Необходима программа отслеживающая завершение этого процесса.  smile  smile 

Автор: Yanis 6.9.2006, 09:56
Цитата(Irinka @  6.9.2006,  09:38 Найти цитируемый пост)
Есть ярлык, запускающий процесс на удаленном сервере.

Ярлык на локальном компьютере, который запускает программу на удалённом?
Не врубился....

Автор: _hunter 6.9.2006, 10:45
ищи на форуме доку по работе с ярлыками -- получиш путь к запускаемому приложению.
а потом как обычно -- CreateProcess + WaitForSingleObject

Автор: Alexeis 6.9.2006, 11:32
Да это странно, можно с ярлыка запустить программу только на своем компьютере. Либо на той стороне должен быть "исполнитель", который запустит программу после передачи ему определенной команды.

Автор: BUGOR 6.9.2006, 13:32
Может речь об удалённом рабочем столе. Короче вопрос не ясен.

Автор: Yanis 6.9.2006, 13:35
В любом случае программа должна работать на той стороне где запускается требуемый процесс.

Автор: Irinka 6.9.2006, 13:39
да, речь идет об удаленном рабочем столе...

Автор: Yanis 6.9.2006, 14:30
Ну и что? За тебя нужно программу написать что ли? Что нужно то? Запустить и отследить завершение программы очень просто.
http://vingrad.ru/DELPHI-DLP-000765

Даль ше то, что? Ты что стешняешься?

Автор: Irinka 7.9.2006, 07:28
Мне не нужно запускать программу, она запускается из другого приложения и создает определенный процесс, мне нужно отследить  завершение этого процесса

Автор: _hunter 7.9.2006, 10:33
ну тогда поиск на форуме на тему "список окон" или "список процессов"

Автор: Yanis 7.9.2006, 11:40
Irinka
Вот накатал специально для тебя примерчик. Надеюсь поможет smile

Код
{*
* Функция возвращает PID процесса
* szFileName - имя искомого процесса (можно передавать путь к файлу целиком)
* Функция возвращает PID первого найденого процесса с именем szFileName
* Если процесс не найден, то возвращает 0
*
* Function retrieve the the process Id
* szFileName - process file name to search for
* Return value - dwProcessId of first founded process with name szFileName
* If process szFileName not founded, then return value is NULL
*}

function FindProcess(const szFileName: string): DWORD;
var
  fn: string;
  aProcesses: array[0..1023] of DWORD;
  cbNeeded, cProcesses, hProcess, hMod: DWORD;
  i: Integer;
  szProcessName: array[0..MAX_PATH - 1] of Char;
begin
  Result := 0;

  // вдруг нам передали путь к файлу целиком
  fn := ExtractFileName(szFileName);

  if not EnumProcesses(@aProcesses, SizeOf(aProcesses), cbNeeded) then
    Exit;

  // кол-полученое кол-во процессов
  cProcesses := cbNeeded div SizeOf(cProcesses);

  for i := 0 to cProcesses - 1 do
    begin
      // получаем хэндл процесса, что бы узнать имя исполняемого файла
      hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
        False,
        aProcesses[i]);

      // если удалось открыть объект - процесс, то
      if hProcess > 0 then
        begin
          // перечисляем все модули процесса
          if EnumProcessModules(hProcess, @hMod, SizeOf(hMod), cbNeeded) then
            GetModuleBaseName(hProcess, hMod, szProcessName, SizeOf(szProcessName));

          // сравниваем с нашим (искомым) процессом
          if AnsiCompareText(szProcessName, fn) = 0 then
            Result := aProcesses[i];
        end;

      // закрываем описатель. Он нам больше не нужен
      CloseHandle(hProcess);
    end;
end;


Далее привожу пример, как отыскать процесс с именем notepad.exe и подождать его завершения:
Код
var
  dwProcessId, hProcess: DWORD;
begin
  dwProcessId := FindProcess('notepad.exe');

  if dwProcessId > 0 then
    if Application.MessageBox(PChar('Ждать завершения процесса с PID = ' + IntToStr(dwProcessId)),
      nil,
      MB_ICONQUESTION or MB_YESNO) = ID_YES then
      begin
        hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or SYNCHRONIZE, False, dwProcessId);
        if hProcess > 0 then
          begin
            Application.MessageBox(PChar('Программа продолжит работу после завершения процесса notepad.exe (PID = ' + IntToStr(dwProcessId) + ')'),
                                   nil, MB_ICONWARNING);

            // теперь программа продолжит работу
            // только после завершения процесса notepad.exe
            while WaitForSingleObject(hProcess, 100) <> WAIT_OBJECT_0 do
              Application.ProcessMessages;

            CloseHandle(hProcess);

            // здесь располагается код для выполенния действий
            // после завершения процесса notepad.exe

            Application.MessageBox(PChar('Процесс notepad.exe (PID = ' + IntToStr(dwProcessId) + ') завершил своё существование'),
                                   nil, MB_ICONINFORMATION);
          end;
      end;
end;

Автор: Irinka 7.9.2006, 15:04
Пример мне помог, но не до конца,  smile  возникла проблема с тем что этот процесс, буду называть его процесс1 при завершении запускает еще один процесс - процесс2. А тот в свое время опять может запустить первый. Мне необходимо сделать проверку следующего вида, если процесс1 and процесс2 отработали, тогда выход. С программой такого вида сталкиваюсь первый раз, поэтому у меня большие трудности...

Автор: _hunter 7.9.2006, 15:31
крути два цикла (по циклу на процесс)

Автор: Yanis 7.9.2006, 15:52
Irinka
Какие проблемы? Достаточно переделать функцию, что бы она принимала 2 параметра - имена процессов, а возвращала например массив (ну или указатель на него) с двумя значениями - PID первого и второго процесса. Потом в моём примере делать OpenProcess для 2х процессов.

P. S. А сразу нельзя было сказать поточнее? smile

Добавлено @ 15:57 
Только что прочитал и сам удивился, что я сказанул smile

Достаточно дава раза вызвать функцию FindProcess для двух процессов, открыть (OpenProcess) их получив тем самым их описатель (т.е. hProcess1, hProcess2) и использовать такую конструкцию:

Код
while (WaitForSingleObject(hProcess1, 100) <> WAIT_OBJECT_0) and (WaitForSingleObject(hProcess2, 100) <> WAIT_OBJECT_0) do
  Application.ProcessMessages;

Автор: MetalFan 14.2.2007, 15:09
случайно на тему напоролся)
а почему бы в последнем примере не использовать WaitForMultipleObjects?

Автор: Yanis 14.2.2007, 15:27
Цитата(MetalFan @  14.2.2007,  16:09 Найти цитируемый пост)
а почему бы в последнем примере не использовать WaitForMultipleObjects?

Действительно. Из головы наверное тогда вылетело smile Можно и её юзать. 
Надеюсь всем кто изучал этот вопрос и натыкался на тему, понятно как применить WaitForMultipleObjects smile

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