Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Запуск консольного приложения из программы. [D2005, 2000]


pathfinder ©   (2007-05-17 10:50:00) 

Добрый день.
Подскажите пожалуйста, как запустить консольное приложение из кода программы и получить код возврата? Нужно для тестирования архива консольным архиватором.


pathfinder   (2007-05-18 09:20:00) [1]


> В справке например инициализируется только cb.


т.е. в примере который приведен в справке к делфи2006


pathfinder   (2007-05-18 09:18:00) [2]

в итоге получилось следующее:

function ProgExec(s: String; m: Uint): Integer;
var
 ProcInfo  : TProcessInformation;
 StartInfo : TStartUpInfo;
 ExitCode  : DWord;
begin
 Result := -1;

 ZeroMemory(@StartInfo, SizeOf(StartInfo));
 ZeroMemory(@ProcInfo , SizeOf(ProcInfo ));

 with StartInfo do
   begin
      cb          := SizeOf(StartInfo);
      lpdesktop   := nil;
      lptitle     := nil;
      dwflags     := STARTF_USESHOWWINDOW;
      wshowwindow := m;
   end;

 if CreateProcess(nil,
                  PChar(s),
                  nil,
                  nil,
                  False,
                  0,
                  nil,
                  nil,
                  StartInfo,
                  ProcInfo
                  )
 then begin
        WaitForSingleObject(ProcInfo.hprocess, infinite);
        GetExitCodeProcess (ProcInfo.hprocess, ExitCode);
        Result:=ExitCode;
        closehandle(ProcInfo.hthread);
        closehandle(ProcInfo.hprocess);
      end;
end;

Подскажите пожалуйста, нет ли здесь ошибок?

И еще такой вопрос: какие поля структуры startupinfo необходимо инициализировать? В справке например инициализируется только cb.


Сергей М.   (2007-05-17 15:28:00) [3]


> pathfinder ©   (17.05.07 15:25) [9]


В принципе - по барабану в какой последовательности.
Но если заниматься ловлей блох, то логичней закрыть сначала хэндл потока.


pathfinder   (2007-05-17 15:25:00) [4]

а в какой последовательности закрываются дескрипторы процесса и осн. потока?


Сергей М.   (2007-05-17 15:10:00) [5]


> losehandle(lpprocessinformation.hprocess); разве не закрывает?
>
>


Закрывает, но не хэндл потока, а хендл процесса.
А нужно еще закрыть хэндл потока (lpprocessinformation.hThread), в противном  случае это чревато утечкой ресурсов.


pathfinder   (2007-05-17 14:14:00) [6]


> недостаточный размер p, (и, во-ще, все приседания с p лишние)

т.е. вот так?

function Test_Prog( s : String; m : Uint) : Integer;
var
lpprocessinformation : TProcessInformation;
lpstartupinfo           : TStartUpInfo;
p                          : array[0..254] of char;
ExitCode                : DWord;
begin
Result := -1;
FillChar(lpstartupinfo, SizeOf(tstartupinfo), $00);
with lpstartupinfo do
  begin
     lpdesktop   := nil;
     lptitle     := nil;
     dwflags     := STARTF_USESHOWWINDOW;
     wshowwindow := m;
  end;
if CreateProcess(nil, PChar(s), nil, nil, False, CREATE_DEFAULT_ERROR_MODE, nil, nil,
   lpstartupInfo, lpprocessInformation) then
  begin
     WaitForSingleObject(lpprocessinformation.hprocess, infinite);
     GetExitCodeProcess (lpprocessinformation.hprocess, ExitCode);
     Result:=ExitCode;
     closehandle(lpprocessinformation.hprocess);
 end;
end;


> не закрывается хендл потока.

а closehandle(lpprocessinformation.hprocess); разве не закрывает?


Leonid Troyanovsky   (2007-05-17 13:30:00) [7]


> pathfinder ©   (17.05.07 12:35) [2]

> Корректен ли он? Можно ли применять его в таком виде или
> лучше что-то исправить?

В коде, по-крайней мере, 3 ошибки:
недостаточный размер p, (и, во-ще, все приседания с p лишние)
не задан lpstartupinfo.cb
не закрывается хендл потока.

--
Regards, LVT.


pathfinder   (2007-05-17 13:15:00) [8]

Спасибо.


Сергей М.   (2007-05-17 13:08:00) [9]


> по поводу параметра CreateProcess - dwCreationFlags. Какое
> значение там лучше указывать в моем случае?


В твоем случае это не принципиально. Можешь даже 0 указать.


> не лучше ли задавать там таймаут?


см. [3]


ANB   (2007-05-17 12:57:00) [10]


> не лучше ли задавать там таймаут?

Если задать таймаут, то придется функцию вызывать в цикле с анализом ее результата.


pathfinder   (2007-05-17 12:35:00) [11]

нашел следующий код:

function Test_Prog( s : String; m : Uint) : Integer;
var
 lpprocessinformation : TProcessInformation;
 lpstartupinfo           : TStartUpInfo;
 p                          : array[0..254] of char;
 ExitCode                : DWord;
begin
 Result := -1;
 FillChar(lpstartupinfo, SizeOf(tstartupinfo), $00);
 with lpstartupinfo do
   begin
      lpdesktop   := nil;
      lptitle     := nil;
      dwflags     := STARTF_USESHOWWINDOW;
      wshowwindow := m;
   end;
 FillChar(p, sizeof(p), $00);
 StrPCopy(p, s);
 if CreateProcess(nil, P, nil, nil, False, CREATE_DEFAULT_ERROR_MODE, nil, nil,
    lpstartupInfo, lpprocessInformation) then
   begin
      WaitForSingleObject(lpprocessinformation.hprocess, infinite);
      GetExitCodeProcess (lpprocessinformation.hprocess, ExitCode);
      Result:=ExitCode;
      closehandle(lpprocessinformation.hprocess);
  end;
end;

Корректен ли он? Можно ли применять его в таком виде или лучше что-то исправить?

У меня возник вопрос по поводу параметра CreateProcess - dwCreationFlags. Какое значение там лучше указывать в моем случае?

И по поводу второго параметра WaitForSingleObject, не лучше ли задавать там таймаут?


Сергей М.   (2007-05-17 11:03:00) [12]


> как запустить


см. CreateProcess


> получить код возврата


см. WaitForSingleObject + GetExitCodeProcess


Наверх

Титульная страница Поиск, карта сайта Написать письмо