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


Автор: Dom 25.3.2011, 19:57
Задача такая. Запустить консольное приложение с набором параметров командной строки. Дождаться завершения. Запустить следующее консольное приложение и т.д.

Пробовал ShellExecute, WinExec, CreateProcess - не получается.

Вот есть такой код, процедура ExecAndWait позаимствована у http://forum.vingrad.ru/index.php?showtopic=324441&view=findpost&p=2312203
Код

procedure TForm1.Button1Click(Sender: TObject);

function ExecAndWait(const FileName, Params: string; ArcDir:string;
                               const WinState: Word): boolean; export;
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: String;
begin
  CmdLine := '"' + Filename + '" ' + Params;
  FillChar(StartInfo, SizeOf(StartInfo), #0);
  with StartInfo do
  begin
    cb := SizeOf(StartInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    wShowWindow := WinState;
  end;
  Result := CreateProcess(nil, PChar(CmdLine), nil, nil, false,
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
                          PChar(ArcDir), StartInfo, ProcInfo);
  if Result then
  begin
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;

var
  ExeFileName, Params, Dir: string;
begin
  ExeFileName := 'D:\INSTALL\Math\libSVM\libsvm-3.0\windows\svm-scale.exe';
  Params := '-l 0 -u 1 -s D:\temp\libtest\1.svm.train0.range D:\temp\libtest\1.svm.train0 > D:\temp\libtest\1.svm.train0.scaled';
  Dir := 'D:\temp\libtest\';
  ExecAndWait(ExeFileName, Params, Dir, 0);
end;


Формируется правильный CmdLine, но при вызове CreateProcess ничего не происходит, приложение не запускается, новые файлы не создаются.
Если строку полученную в CmdLine скопировать и вставить вручную в командную строку, то все отрабатывает корректно. Т.е. проблема где-то в самом  вызове. Подтолкните пожалуйста в нужное направление, ибо силы уже на исходе...
Наверняка какую-то мелочь пропустил...

Автор: uwannadie 25.3.2011, 22:43
попробуй такой код:
Код

function WinExecute(CmdLine: string; Wait: Boolean): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInformation: TProcessInformation;
begin
  Result := True;
  try
    FillChar(StartupInfo, SizeOf(StartupInfo), 0);
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.wShowWindow := SW_SHOWMINIMIZED;
    if not CreateProcess(nil, PChar(CmdLine), nil, nil, False, CREATE_NO_WINDOW, nil, //тут окошко делается инвизовым, поменять при надобности
    nil, StartupInfo, ProcessInformation) then
      RaiseLastWin32Error;
    if Wait then
      WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
  except
    Result := False;
  end;
end;

у меня по-крайней мере запускалось без ошибок и отрабатывало несколько десятков тысяч раз за один запуск программы   smile 
p.s. код может изначально и был от Акеллы, но найден в просторах тырнета, так что чесно хз чей smile 

Автор: Dom 26.3.2011, 01:27
Спасибо, но не помогло...
Процесс как и прежде не запускается, по крайней мере я не вижу его в ProcessExplorer'е
Будем думать дальше.

Автор: uwannadie 28.3.2011, 09:56
а Вы уверены, что вообще дело доходит до запуска?

Автор: Данкинг 28.3.2011, 10:51
Dom, http://forum.vingrad.ru/index.php?showtopic=324441&view=findpost&p=2312140 глянь-таки на мой пример. Вдруг он тебе поможет. В отличие от CreateProcess. 

Автор: CodeMonkey 28.3.2011, 20:26
Меня вот это смущает: '>' (это в командной строке). Выглядит очень подозрительно. Я сомневаюсь, что это параметр к программе.

Это часом вы не перенаправление вывода сделать хотите?

Автор: uwannadie 29.3.2011, 11:24
Цитата(CodeMonkey @  28.3.2011,  20:26 Найти цитируемый пост)

Это часом вы не перенаправление вывода сделать хотите? 

кстати да, если перенаправление, то тут, увы, ничего не выйдет, ибо перенаправление вывода консоли умеет делать только сама консоль.
для примера попробуйте скомпилировать это:
Код

program Project1;
uses
  SysUtils ,Windows, ShellAPI;

begin
  try
    ShellExecute(GetDesktopWindow, 'open', 'ping.exe', 'ya.ru > d:\result.txt','', SW_NORMAL);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

на диске D ничего не появится smile 

Автор: CodeMonkey 29.3.2011, 11:32
Цитата(uwannadie @  29.3.2011,  12:24 Найти цитируемый пост)
ничего не выйдет


Отчего же. Вполне выйдет. И даже несколькими способами.

Например, через hStdOutput. Или вызовом через CMD.

Но для начала надо точно уточнить, что автор темы хочет сделать.

Автор: uwannadie 29.3.2011, 12:18
Цитата(CodeMonkey @  29.3.2011,  11:32 Найти цитируемый пост)
Например, через hStdOutput. Или вызовом через CMD.

имелся ввиду способ вышеописанными процедурами и функциями

Автор: CodeMonkey 29.3.2011, 13:11
Непонятно, а что не так с вышеуказанными функциями? hStdOutput - это параметр у StartupInfo для CreateProcess. Берём и указываем.

Или имелось ввиду без модификации кода выше? Ну, способ с hStdOutput без модификации - да, нельзя. Хотя в первом примере даже STARTF_USESTDHANDLES есть (но почему-то нет установки самих описателей. Кто это писал? Пристрелить на месте!  smile  ).

Способ через CMD - вполне. Скажем:

Код
var
  Cmd: String;
begin
  Cmd := ExpandEnviromentString('ComSpec'); // Cmd = 'C:\Windows\system32\cmd.exe';

  ExecAndWait(Cmd, '/C echo > D:\Test.txt', 'C:\', SW_NORMAL);
  // или:
  WinExecute(Format('"%s" /C echo > D:\Test.txt', [Cmd]), True);
end;

Автор: uwannadie 29.3.2011, 18:42
Цитата(CodeMonkey @  29.3.2011,  13:11 Найти цитируемый пост)
Или имелось ввиду без модификации кода выше

именно это и имелось ввиду.
Цитата(CodeMonkey @  29.3.2011,  13:11 Найти цитируемый пост)
 Кто это писал? Пристрелить на месте! 

если Вы имелли ввиду то, что выкладывал я, то оно нарыто гуглом в просторах инета  smile 

Автор: northener 30.3.2011, 00:33
Цитата(uwannadie @  29.3.2011,  18:42 Найти цитируемый пост)
если Вы имелли ввиду то, что выкладывал я, то оно нарыто гуглом в просторах инета 

Имхо, CodeMonkey имеет в виду код в вопросе автора. Но "пристрелить на месте" уважаемого автора (к тому же модератора) я не советовал бы. smile

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