Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.01.2010, 10:56   #1
dudeboy
 
Регистрация: 02.11.2009
Сообщений: 7
По умолчанию Завершение отлаживаемого дочернего процесса

Пишу прилодение которое многократно порождает дочернее приложение и смотрит как долго оно работает. Если лимит времени превышен, то дочерний процесс завершается и функция возвращает значение 'TL' - Time Limit - т.е. превышен интервал ожидания. Проблема в том что дечернее приложение не завершается после окончания работы функции (ProcessExplorer так говорит), а вновь вызванная ниже функция дает нормальный результат работы приложения. Т.е. получается цепочка результатов вызовов функций:
TimeLimit, Accept, TimeLimit, Accept, TimeLimit, Accept ...

Как добиться корректного завершения дочернего процесса ?



PHP код:
function runSolve(CmdLinestringTimeLimitCardinal INFINITEMemoryLimitCardinal INFINITE): String;
var
  
StartUpInfoTStartUpInfo;
  
ProcessInfoTProcessInformation;
  
dbg_Debug_event;
  
runBoolean;
  
tickCardinal;
  
resString;
begin
  res 
:= 'AC';

  
with StartUpInfo do begin
    cb 
:= sizeof(StartUpInfo);
    
lpReserved := nil;
    
lpDesktop := nil;
    
lpTitle := PChar('External program "' CmdLine '"');
    
dwFlags := 0;
    
cbReserved2 := 0;
    
lpReserved2 := nil;
  
end;

  
  
run := CreateProcess(
    
nil,                     //Полный путь к исполняемому модулю программы
    
PChar(runCMDsolve),      //Строка параметров
    
nil,                     //Атрибуты защиты для нового процесса
    
nil,                     //Атрибуты защиты для первого потока созданного приложением
    
False,                   //Флаг наследования от процесса производящего запуск
    
DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS,   //Флаг способа создания процесса и его приоритет
    
nil,                     //Блок среды
    
nil,                     //Текущий диск и каталог
    
StartupInfo,             //Используется для настройки свойств процесса, например расположения окон и заголовок
    
ProcessInfo              //Информация о созданном процессе. Инициализируется самой функцией
  
);



  if 
run then begin
    tick
:=GetTickCount;
    
res := 'AC';

    try

          while 
True do begin
              
if (getTickCount tick) > (TimeLimit*1000then begin
                res 
:= 'TL';
                
TerminateProcess(ProcessInfo.hProcess0);
                break;
              
end;

          if 
not WaitForDebugEvent(dbg100then begin
            Application
.ProcessMessages;
            Continue;
          
end;
          
ContinueDebugEvent(dbg.dwProcessIddbg.dwThreadIdDBG_CONTINUE);

          if (
dbg.dwDebugEventCode EXCEPTION_DEBUG_EVENT) and (dbg.Exception.ExceptionRecord.ExceptionCode <> EXCEPTION_SINGLE_STEP) and (dbg.Exception.ExceptionRecord.ExceptionCode <> EXCEPTION_BREAKPOINTthen begin
            res 
:= 'RE';
            
TerminateProcess(ProcessInfo.hProcess0);
          
end;

          if 
dbg.dwDebugEventCode EXIT_PROCESS_DEBUG_EVENT then break;
        
end;

  
    finally
        
CloseHandle(ProcessInfo.hThread);
        
CloseHandle(ProcessInfo.hProcess);
    
end;

  
end;


  
Result := res;
end

Последний раз редактировалось dudeboy; 05.01.2010 в 12:03.
dudeboy вне форума Ответить с цитированием
Старый 05.01.2010, 12:43   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

http://www.programmersforum.ru/showthread.php?t=12099
mihali4 вне форума Ответить с цитированием
Старый 05.01.2010, 15:34   #3
dudeboy
 
Регистрация: 02.11.2009
Сообщений: 7
По умолчанию

Попробовал сделать через JOB, но результат тотже

Код:
function runSolve(CmdLine: string; TimeLimit: Cardinal = INFINITE; MemoryLimit: Cardinal = INFINITE): String;
var
  StartUpInfo: TStartUpInfo;
  ProcessInfo: TProcessInformation;
  dbg: _Debug_event;
  run: Boolean;
  tick: Cardinal;
  res: String;
  hJob: THandle;
begin

  res := 'RE1';

  with StartUpInfo do begin
    cb := sizeof(StartUpInfo);
    lpReserved := nil;
    lpDesktop := nil;
    lpTitle := PChar('External program "' + CmdLine + '"');
    dwFlags := 0;
    cbReserved2 := 0;
    lpReserved2 := nil;
  end;

  (*  СДЕЛАТЬ ЗАЩИТУ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *)
  run := CreateProcess(
    nil,                     //Полный путь к исполняемому модулю программы
    PChar(runCMDsolve),      //Строка параметров
    nil,                     //Атрибуты защиты для нового процесса
    nil,                     //Атрибуты защиты для первого потока созданного приложением
    False,                   //Флаг наследования от процесса производящего запуск
    DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS,   //Флаг способа создания процесса и его приоритет
    nil,                     //Блок среды
    nil,                     //Текущий диск и каталог
    StartupInfo,             //Используется для настройки свойств процесса, например расположения окон и заголовок
    ProcessInfo              //Информация о созданном процессе. Инициализируется самой функцией
  );



  if run then begin
    hJob := CreateJobObjectA(nil, 'MyJob');
    AssignProcessToJobObject(hjob, ProcessInfo.hProcess);
    tick:=GetTickCount;
    res := 'AC';

	  try
	      while True do begin
      		if (getTickCount - tick) > (TimeLimit*1000) then begin
      		  res := 'TL';
            TerminateJobObject(hJob, 0);
//		        TerminateProcess(ProcessInfo.hProcess, 0);
      		  break;
      		end;

          if not WaitForDebugEvent(dbg, 100) then begin
            Application.ProcessMessages;
            Continue;
          end;
          ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);

          if (dbg.dwDebugEventCode = EXCEPTION_DEBUG_EVENT) and (dbg.Exception.ExceptionRecord.ExceptionCode <> EXCEPTION_SINGLE_STEP) and (dbg.Exception.ExceptionRecord.ExceptionCode <> EXCEPTION_BREAKPOINT) then begin
            res := 'RE';
            TerminateJobObject(hJob, 0);
//            TerminateProcess(ProcessInfo.hProcess, 0);
            break;
          end;

          if dbg.dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT then break;
        end;

    finally
//      TerminateProcess(ProcessInfo.hProcess, 0);
//      TerminateJobObject(hJob, 0);
	    CloseHandle(ProcessInfo.hThread);
	    CloseHandle(ProcessInfo.hProcess);
	  end;

  end;


  Result := res;
end;
dudeboy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Завершение процесса из Паскаля NSvirus Паскаль, Turbo Pascal, PascalABC.NET 3 16.04.2009 20:29
завершение процесса jone Общие вопросы Delphi 14 28.10.2008 17:35
Запрет на завершение процесса Черничный Win Api 5 22.07.2008 20:13
Завершение процесса Terran Win Api 3 04.01.2008 12:09
Завершение процесса антивируса Terran Win Api 7 07.12.2007 22:28