Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ShellExecute, получение ответа о завершении проги 
:(
    Опции темы
Гость_raptor
Дата 18.8.2004, 22:41 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











С помощью ShellExecute вызываю архиватор и извлекаю файлы из архива.после чего извлеченные файлы надо переименовать. проблема в том что прога не ждет завершения работы архиватора и выполняется дальше. как заставить прогу ждать ответа от архиватора о завершения процесса и только после получения положительного ответа переходить к следуещему этапу?
архиватор winrar
delphi 7
sample.gif
спасибо!
  Вверх
<Spawn>
Дата 18.8.2004, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 1
Всего: 64



Делай CreateProcess + WaitForInputIdle


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
megaraptor
Дата 18.8.2004, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 18.8.2004

Репутация: нет
Всего: нет



если не трудно можно пример?
PM MAIL   Вверх
Петрович
Дата 18.8.2004, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 15
Всего: 55



Не трудно smile.gif Вот кусок из модуля. Сходу не странслируется, но суть понять можно. См. процедуру WaitExecuteCommand

Код

...

interface

...

type
 eStartExecuteCommand = class(Exception)
     ErrorCode :Integer;
     constructor Create (aErrorCode :Integer);
   end;

function StartExecuteCommand (const CmdLine       :String;
                             const WorkDirectory :String  ='';
                             const ShowMode      :Integer =SW_SHOWNORMAL
                             ) :tHandle;
// Функция запускает на выполнение команду CmdLine в рамках отдельного
// процесса, и возвращает управление не дожидаясь его завершения.
// WorkDirectory - имя текущего каталога для запускаемого процесса.
// ShowMode      - режим отображения для запускаемого процесса.
// Возвращает описатель запущенного процесса (tProcessInformation.hProcess).
// Ex:
//   eStartExecuteCommand при возникновении ошибки запуска.

type  tIdleProc = procedure (var KillProcess :Boolean);
function WaitExecuteCommand  (const CmdLine       :String;
                             const WorkDirectory :String    ='';
                             const ShowMode      :Integer   =SW_SHOWNORMAL;
                             const IdleProc      :tIdleProc =Nil
                             ) :Cardinal;
// Функция запускает на выполнение команду CmdLine в рамках отдельного
//   процесса, и дожидается его завершения.
// WorkDirectory - имя текущего каталога для запускаемого процесса.
// ShowMode      - режим отображения для запускаемого процесса.
// IdleProc      - процедура вызываемая пока процесс не завершился
// Возвращает код завершения процесса (ExitCode).
// В процессе ожидания завершения порожденного процесса, вызывается
//   Application.ProcessMessages позволяя вызвавшему приложению реагировать на
//   сообщения Windows.
// Если во время ожидания, вызвавшее приложение будет закрыто
//   (Application.Terminated), то порожденный процесс будет принудительно
//   завершён.
// Если задана IdleProc (не Nil), то она вызывается (в контексте вызывающего
//   потока) во время ожидания завершения запущенного процесса. Передаваемый ей
//   параметр CancelProcess имеет начальное значение False, Если процедура
//   изменит его на True, то порожденный процесс будет принудительно завершён.
// *** ВНИМАНИЕ! *** Если запускаемая программа - DOS-программа, то в ее
//   свойствах должно быть указано закрытые окна по завершению работы!
// Ex:
//   eStartExecuteCommand при возникновении ошибки запуска
//                        или при приндительном завершении процесса.

...

implementation

...


constructor eStartExecuteCommand.Create (aErrorCode :Integer);
begin
 ErrorCode := aErrorCode;
 Inherited Create(SysErrorMessage(ErrorCode));
end;

function StartExecuteCommand (const CmdLine       :String;
                             const WorkDirectory :String  ='';
                             const ShowMode      :Integer =SW_SHOWNORMAL
                             ) :tHandle;
// Функция запускает на выполнение команду CmdLine в рамках отдельного
// процесса, и возвращает управление не дожидаясь его завершения.
// WorkDirectory - имя текущего каталога для запускаемого процесса.
// ShowMode      - режим отображения для запускаемого процесса.
// Возвращает описатель запущенного процесса (tProcessInformation.hProcess).
// Ex:
//   eStartExecuteCommand при возникновении ошибки запуска.
const
 CreationFlags = CREATE_NEW_CONSOLE + NORMAL_PRIORITY_CLASS;
 StartupFlags  = STARTF_USESHOWWINDOW + CREATE_SEPARATE_WOW_VDM;
var
 StartUpInfo   :tStartUpInfo;
 ProcessInfo   :tProcessInformation;
 pDir          :pChar;
begin
 {CreateProcess возвращает ошибку, если ему передать пустую строку в WorkDir,
  в этом случае надо передавать Nil}
 if  Length(WorkDirectory) = 0  then
   pDir := Nil
 else
   pDir := pChar(WorkDirectory);

 FillChar(StartupInfo,Sizeof(StartupInfo),#0);
 StartupInfo.cb          := Sizeof(StartupInfo);
 StartupInfo.dwFlags     := StartupFlags;
 StartupInfo.wShowWindow := ShowMode;

 if not CreateProcess(Nil,pChar(CmdLine),Nil,Nil,false,CreationFlags,nil,
                                   pDir,StartupInfo,ProcessInfo)  then
   raise eStartExecuteCommand.Create(GetLastError());

 CloseHandle(ProcessInfo.hThread);
 Result := ProcessInfo.hProcess;
end;


function WaitExecuteCommand  (const CmdLine       :String;
                             const WorkDirectory :String    ='';
                             const ShowMode      :Integer   =SW_SHOWNORMAL;
                             const IdleProc      :tIdleProc =Nil
                             ) :Cardinal;
// Функция запускает на выполнение команду CmdLine в рамках отдельного
//   процесса, и дожидается его завершения.
// WorkDirectory - имя текущего каталога для запускаемого процесса.
// ShowMode      - режим отображения для запускаемого процесса.
// IdleProc      - процедура вызываемая пока процесс не завершился
// Возвращает код завершения процесса (ExitCode).
// В процессе ожидания завершения порожденного процесса, вызывается
//   Application.ProcessMessages позволяя вызвавшему приложению реагировать на
//   сообщения Windows.
// Если во время ожидания, вызвавшее приложение будет закрыто
//   (Application.Terminated), то порожденный процесс будет принудительно
//   завершён.
// Если задана IdleProc (не Nil), то она вызывается (в контексте вызывающего
//   потока) во время ожидания завершения запущенного процесса. Передаваемый ей
//   параметр CancelProcess имеет начальное значение False, Если процедура
//   изменит его на True, то порожденный процесс будет принудительно завершён.
// *** ВНИМАНИЕ! *** Если запускаемая программа - DOS-программа, то в ее
//   свойствах должно быть указано закрытые окна по завершению работы!
// Ex:
//   eStartExecuteCommand при возникновении ошибки запуска
//                        или при приндительном завершении процесса.
const
 SuspendTime = 200; // время (в милисекундах) на которое вызывающий процесс
                    //    приостанавливается в цикле ожидания
var
 hProcess :tHandle;
 KillProcess   :Boolean;
 ProcessKilled :Boolean;
begin
 // запуск процесса
 hProcess := StartExecuteCommand(CmdLine,WorkDirectory,ShowMode);
 try
   // процесс успешно запущен, ждём завершения
   KillProcess   := False;
   ProcessKilled := False;
   repeat
     Application.ProcessMessages;
     KillProcess := ProcessKilled;
     if  Assigned(IdleProc) then  IdleProc(KillProcess);
     if  (KillProcess or Application.Terminated) and  not ProcessKilled  then begin
       TerminateProcess(hProcess,ERROR_PROCESS_ABORTED);
       ProcessKilled := True;
     end;
   until (WaitforSingleObject(hProcess,SuspendTime)<>WAIT_TIMEOUT);
   if  ProcessKilled  then
     raise eStartExecuteCommand.Create(ERROR_PROCESS_ABORTED); // Процесс принудительно завершен.
   // узнаем код завершения процесса
   if  not GetExitCodeProcess(hProcess,Result)  then
     // Хм, Ошибка? Что-бы это могло быть?
     raise eStartExecuteCommand.Create(GetLastError());
 finally
   CloseHandle(hProcess);
 end;
end;

...



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
pc_cpu
Дата 19.8.2004, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 11.7.2004
Где: г. Фурманов Ивано вской обл.

Репутация: нет
Всего: нет



Когда нужно дождаться закрытия Exe-хи, а потом ее удалить, то я делаю так:
Код
repeat
until deletefile(filename);

Может и тут так же получится (скопируй куда - нибудь архив, если он тебе потом потребуется).
PM MAIL ICQ   Вверх
Pakshin A. S.
Дата 19.8.2004, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: нет
Всего: 61



pc_cpu
Прога виснет, память жрётся, время уходит... А если архив в 200 Мб?!
PM   Вверх
pc_cpu
Дата 19.8.2004, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 11.7.2004
Где: г. Фурманов Ивано вской обл.

Репутация: нет
Всего: нет



Можно в принципе таймер использовать. В любом случае тебе придется периодически что-то проверять [DeleteFile('arhiv.rar')=true, или FileExists('izvlek.doc')=true, или FindWindow(nil,'Извлечение из arhiv.rar')=0 и т.д.].
PM MAIL ICQ   Вверх
Dynamic
Дата 20.8.2004, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 372
Регистрация: 5.7.2004
Где: Салехард

Репутация: нет
Всего: 15



Код
procedure TfmMain.btViewClick(Sender: TObject);
var cmd: string;
   si: TStartupInfo;
   pi: TProcessInformation;
begin
    FillChar(si, SizeOf(si), 0);
    with si do
    begin
      cb := SizeOf(si);
      dwFlags := STARTF_USESHOWWINDOW;
      wShowWindow := SW_HIDE;  // или SW_SHOWNORMAL
    end;
    cmd := // командная строка с параметрами
    CreateProcess(nil, PChar(cmd), nil, nil, false, CREATE_DEFAULT_ERROR_MODE,
      nil, nil, si, pi);
    WaitForSingleObject(pi.hProcess, INFINITE);

    // процесс отработал, можешь проверять результат

end;



--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
Петрович
Дата 21.8.2004, 02:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 15
Всего: 55



Цитата(Dynamic @ 20.8.2004, 13:07)
WaitForSingleObject(pi.hProcess, INFINITE);

Ой, не люблю я как-то все эти бесконечные (INFINITE) ожидания smile.gif. А если это делать еще и в Main-потоке, то убивать порой приходится исключительно Task Manager'ом smile.gif.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Messages
Дата 21.8.2004, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 26.3.2004

Репутация: нет
Всего: нет



Я толком не знаю, но неужели ShellExecute ни какого хендла не возврощает?

Или альтернатива выкрать hwnd прогресс бара с окошка rar'ы и свой такойже заиметь.

Бред, какой-то!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0882 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.