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


Автор: MrDmitry 11.3.2011, 01:59
Пишу не большую программку, программка в ходе своей работы, должна запустить внешнею утилиту(hldsupdatetool), дождаться её завершения и начать выполнять другие действия. То есть нужно чтоб код идущий после запуска внешнего приложения не выполнялся пока не будет завершено это приложение. В интернете полно всяких готовых решений, но в них куча ошибок, а те которые удалось исправить, не работают как нужно

Автор: northener 11.3.2011, 02:45
Вообще-то CreateProcess вполне достаточна для решения сабжа. И во всемирной помойке достаточно примеров её использования. Что именно не получается?
Ну и "в них куча ошибок". Не верю. Это не в них куча ошибок, это ты используешь их неправильно. Ибо не понимаешь их. 

Автор: Данкинг 11.3.2011, 02:54
Код

uses comobj;
...
procedure TForm1.Button1Click(Sender: TObject);
var fo:variant;
begin
 fo:=createoleobject('WScript.Shell');
 fo.run('proga.exe',1,true);
 fo:=unassigned;
end;


Добавлено через 1 минуту и 13 секунд
Цитата(northener @  11.3.2011,  02:45 Найти цитируемый пост)
Вообще-то CreateProcess вполне достаточна для решения сабжа. 

Да ладно. Сам пробовал все эти CreateProcess и прочие WinExec - ни разу не получилось.

Автор: northener 11.3.2011, 06:48
Цитата(Данкинг @  11.3.2011,  02:54 Найти цитируемый пост)
Да ладно. Сам пробовал все эти CreateProcess и прочие WinExec - ни разу не получилось.

Хм. Вот от вас не ожидал такого ответа.

Автор: Molodec 11.3.2011, 09:55
В библиотеке JVCL находил компонент для запуска приложения. Может в нем есть и callback функция, которая выполняется при завершении работы приложения. Может здесь стоит "покапать"...
Удачи! 

Автор: Akella 11.3.2011, 09:57
уже не раз на форуме давал этот код:

Код

function TfmMain.ExecAndWait(const FileName, Params: ShortString; ArcDir:string;
                               const WinState: Word): boolean; export;
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: ShortString;
begin
  { Помещаем имя файла между кавычками, с соблюдением всех пробелов в именах Win9x }
  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( String( CmdLine ) ), nil, nil, false,
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
                          PChar(ArcDir),StartInfo,ProcInfo);
  { Ожидаем завершения приложения }
  if Result then
  begin
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    { Free the Handles }
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;


Используем так, на примере с распаковкой/упаковкой файлов с пом. программы winrar:
Код

//распаковываем все архивы в указаном каталоге и подкаталогах

Procedure TfmUpdateInfo.ExtractArchives(Dir: String);
Var
 SearchRec:TSearchRec;
begin
 try

   if Dir<>'' then Dir:=IncludeTrailingPathDelimiter(Dir);

   if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then
     repeat
       if (SearchRec.name='.') or (SearchRec.name='..') then continue;
       if ((SearchRec.Attr and faDirectory)<>0) then
         ExtractArchives(Dir+SearchRec.name) //we found Directory: "Dir+SearchRec.name"
       else
        begin
          if AnsiUpperCase(ExtractFileExt(SearchRec.name)) = '.RAR' then
          begin

              //распаковываем и ожидаем окончания распаковки
              fmMain.ExecAndWait(<путь к winrar>, 'e -ep -y ' + SearchRec.name, dir, 0);

              //удаляем распакованный архив (хотя можно указать ключ и winrar сам может удалять архив)
              DeleteFile(dir + SearchRec.name);

          end;//if ExtractFileExt(SearchRec.name)='.rar' then
        end;//else
     until FindNext(SearchRec)<>0;

 finally
   FindClose(SearchRec);
 end;
end;


этот код проверен во всех виндах, начиная с 98, на 95 не проверялось

Автор: Данкинг 11.3.2011, 10:29
Цитата(northener @  11.3.2011,  06:48 Найти цитируемый пост)
Хм. Вот от вас не ожидал такого ответа. 

Так я же не виноват, что не получилось. smile А вот WScript отлично работает, причём не только из Дельфи.

Автор: bems 11.3.2011, 14:16
Цитата(Данкинг @  11.3.2011,  10:29 Найти цитируемый пост)
Так я же не виноват, что не получилось
Боюсь виноват именно ты. Потому что CreateProcess работает как надо.

Автор: Данкинг 11.3.2011, 14:20
Цитата(bems @  11.3.2011,  14:16 Найти цитируемый пост)
Боюсь виноват именно ты.

Конечно, именно я, кто же ещё. smile Только интересно, почему мне минус поставили за рабочий и, главное, простой и понятный код? smile В котором нет тучи ненужных параметров, как в CreateProcess, от которых толку всё равно никакого, потому что, как я уже говорил, этот CreateProcess так как надо всё равно не работает. smile 


Автор: CodeMonkey 11.3.2011, 14:26
Потому что ты не сумел завернуть шуруп отвёрткой и забил его молотком. Даже хуже.

Автор: Данкинг 11.3.2011, 15:59
Цитата(CodeMonkey @  11.3.2011,  14:26 Найти цитируемый пост)
Потому что ты не сумел завернуть шуруп отвёрткой и забил его молотком. Даже хуже.

Что хуже, если у меня пример проще некуда? Кроме Comobj никаких библиотек не требует, тучи непонятных простому смертному параметров, как я уже говорил, тоже не просит, занимает 3 строчки кода и работает стопроцентно верно?

Автор: bems 11.3.2011, 16:36
Во-первых совершенно не обязательно использовать ole для такой простой вещи, как запуск процесса. Во-вторых в CreateProcess все параметры понятны. Если они непонятны лично тебе, это не повод обобщать.

Автор: Данкинг 11.3.2011, 17:34
Цитата(bems @  11.3.2011,  16:36 Найти цитируемый пост)
Во-вторых в CreateProcess все параметры понятны.

Т.е. мой код менее понятен, чем значение параметров в CreateProcess? 

Автор: bems 11.3.2011, 18:04
Твой код вполне понятен, но это гoвнoкод. Не нужно создавать ком-объект сервера сценариев чтобы запустить процесс. Нужно просто взять и запустить.

Автор: Данкинг 11.3.2011, 18:48
Угу. Ваш хвалёный CreateProcess (для него, оказывается, ко всему прочему какие-то никому не нужные переменные надо задавать) у меня вообще не запустился, только что попробовал.  smile Не говоря уж о том, что требуется топикстартеру (кстати, посмотрим, что выберет он сам). В общем, флуд завершаю, а своего мнения всё равно не изменю. smile 

Автор: bems 11.3.2011, 21:42
В процессе программирования нужны переменные, какой кошмар. 
А то что он у тебя не запустился, так тут ключевая фраза "у тебя"

Автор: CodeMonkey 11.3.2011, 23:30
Цитата(Данкинг @  11.3.2011,  16:59 Найти цитируемый пост)
Что хуже, если у меня пример проще некуда? Кроме Comobj никаких библиотек не требует, тучи непонятных простому смертному параметров, как я уже говорил, тоже не просит, занимает 3 строчки кода и работает стопроцентно верно? 


Я на тебя посмотрю, когда WSH будет не установлен в системе, или ты будешь вызывать этот код в других условиях, когда добрая Delphi не вызовет за тебя OleInitialize. Отдельный привет именам с пробелами. Не говоря уже про то, что Run - аналог ShellExecute. Т.е. если файловой ассоциации нет, то фиг ты запустишь.

Автор: Данкинг 11.3.2011, 23:34
Ещё в качестве флуда. smile Вечером на работу к нас зашёл программер, который уволился недели 3 назад. Выпили коньячку, и сказал я ему о том, что на Винграде спорим о том, как %сабж%. И вот что он ответил: "Самое простое, что я видел - это..." Далее предоставляю право догадаться, что именно он ответил. smile  smile 
Цитата(bems @  11.3.2011,  21:42 Найти цитируемый пост)
В процессе программирования нужны переменные, какой кошмар. 

Ага, нужны. Только тут дело в том, что объявлять их требуется для CreateProcess, но вот далее оные нигде не используются.

Автор: CodeMonkey 11.3.2011, 23:36
Несомненно, самое простое что я видел для закручивания шурупов - это молоток.

Продолжай в том же духе - так придём к светлому будущему, товарищ!

Автор: Данкинг 11.3.2011, 23:59
Цитата(CodeMonkey @  11.3.2011,  23:30 Найти цитируемый пост)
когда добрая Delphi не вызовет за тебя OleInitialize.

На фоксе этот код тоже отлично работает.
Цитата(CodeMonkey @  11.3.2011,  23:30 Найти цитируемый пост)
Не говоря уже про то, что Run - аналог ShellExecute. Т.е. если файловой ассоциации нет, то фиг ты запустишь.

Если нет файловой ассоциации с .exe - значит, пора винду переустанавливать или же откатывать на момент установки. smile
Цитата(CodeMonkey @  11.3.2011,  23:36 Найти цитируемый пост)
Несомненно, самое простое что я видел для закручивания шурупов - это молоток.

Молотком шуруп куда сложнее забивать, нежели запустить программу с помощью моего кода. smile Плюс, повторюсь снова и снова, никаких лишних переменных.

Добавлено @ 00:02
Цитата(CodeMonkey @  11.3.2011,  23:30 Найти цитируемый пост)
Отдельный привет именам с пробелами. 

Тебе взаимный привет от двойных кавычек, обрамляющих путь к программе. smile 

Автор: northener 12.3.2011, 02:01
Цитата(Данкинг @  11.3.2011,  23:59 Найти цитируемый пост)
Цитата(CodeMonkey @  11.3.2011,  23:30 Найти цитируемый пост)
Не говоря уже про то, что Run - аналог ShellExecute. Т.е. если файловой ассоциации нет, то фиг ты запустишь.

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


Вы же сами упоминали про топик стартера. А где в его вопросе точное указание, что ему нужно просто запустить произвольный EXE-шник?
Он же пишет свою программу не "для просто так"? И это явно не вариант shell'а, иначе зачем нужно дожидаться завершения работы запущенного приложения. Для меня из текста вопроса ясно, что автор в своей программе готовит какие-то данные для последующей обработки другой программой. Он должен дождаться завершения этой обработки, после чего должен продолжить свою работу уже имея готовый результат другой программы. А в этом случае ваш вариант плохо подходит.
Точнее, совсем не подходит!

Автор: bems 12.3.2011, 09:24
Цитата(Данкинг @  11.3.2011,  23:34 Найти цитируемый пост)
Только тут дело в том, что объявлять их требуется для CreateProcess, но вот далее оные нигде не используются. 
Используется для передачи хендла процесса в Wait-функцию. И не надо привлекать мифических соратников на свою сторону, тебе же три человека говорят прямо здесь что это неправильно. 
И перестань смайлофажить, ты не в песочнице.

Автор: Данкинг 12.3.2011, 14:35
Цитата(bems @  12.3.2011,  09:24 Найти цитируемый пост)
И не надо привлекать мифических соратников на свою сторону

Почему мифических? Почему привлекать? Я спросил, как бы сделал он сам, ничего не говоря ни о ole, ни о createprocess.
Цитата(bems @  12.3.2011,  09:24 Найти цитируемый пост)
тебе же три человека говорят прямо здесь что это неправильно. 

Да-да, только кроме меня и Акеллы кода никто не написал. Все только говорят, что это неправильно, но правильного кода никто не приводит. Мне одному кажется, что что-то не так?
Цитата(bems @  12.3.2011,  09:24 Найти цитируемый пост)
И перестань смайлофажить, ты не в песочнице.

Не знаю, что такое "смайлофажить", видимо, что-то со смайликами связано. А разве смайлики можно употреблять только в песочнице? smile 
Цитата(northener @  12.3.2011,  02:01 Найти цитируемый пост)
А где в его вопросе точное указание, что ему нужно просто запустить произвольный EXE-шник?

Речь идёт о запуске утилиты. Ну, утилита может быть и .com, это сути не меняет. smile 
Цитата(northener @  12.3.2011,  02:01 Найти цитируемый пост)
после чего должен продолжить свою работу уже имея готовый результат другой программы. А в этом случае ваш вариант плохо подходит.

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

Автор: bems 12.3.2011, 17:48
Цитата(Данкинг @  12.3.2011,  14:35 Найти цитируемый пост)
Почему мифических? 
потому что это миф.
Цитата(Данкинг @  12.3.2011,  14:35 Найти цитируемый пост)
Да-да, только кроме меня и Акеллы кода никто не написал. Все только говорят, что это неправильно, но правильного кода никто не приводит. Мне одному кажется, что что-то не так?
Походу да, тебе одному. Акелла показал в принципе правильный код, только с парочкой флагов, которые могут быть и не нужны, и нечего тут еще показывать.

Тема скатилась, закрываю.

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