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

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

Запуск приложения и ождание завершения, при этом форма активна [D7]


Страницы:   1 2

cruiser ©   (2008-10-22 22:46:00) 

Уважаемые Мастера! Столкнулся с проблемкой. Вот код от которого я отталкиваюсь:
function RunAny(CommandLine: string; Memo1: TMemo): boolean;
var
  I: byte;
  S: string;
  Flag: boolean;
  tRead, cWrite, dwRead, dwAvail: cardinal;
  SA: TSecurityAttributes;
  PI: TProcessInformation;
  SI: TStartupInfo;
begin
  Result:=False;
  SA.nLength:=SizeOf(SECURITY_ATTRIBUTES);
  SA.bInheritHandle:=True;
  SA.lpSecurityDescriptor:=nil;
  if not CreatePipe(tRead, cWrite, @SA, 0) then Exit;
  ZeroMemory(@SI, SizeOf(TStartupInfo));
  SI.cb:=SizeOf(TStartupInfo);
  SI.dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
  SI.wShowWindow:=SW_HIDE;
  SI.hStdOutput:=cWrite;
   if CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, nil, SI, PI) then begin

     CloseHandle(PI.hProcess);
     CloseHandle(PI.hThread);
  Memo1.Clear;
     Flag:=True;
     while Flag do begin
        for I:=0 to 9 do begin
           PeekNamedPipe(tRead, nil, 0, nil, @dwAvail, nil);
           if (dwAvail>0) then begin
              Flag:=True;
              Break;
           end
           else Flag:=False;
   if CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, nil, SI, PI) then
  begin
WaitForSingleObject(PI.hProcess, 100);
   CloseHandle(PI.hProcess);
end;
        end;
        if dwAvail>0 then begin
           SetLength(S, dwAvail);
           ReadFile(tRead, PChar(S)^, Length(S), dwRead, Nil);
           OemToChar(PChar(S), PChar(S));
           Memo1.Lines.Add(S);
           Application.ProcessMessages;
           Result:=True;

        end; // if dwAvail
     end;    // while Flag
  end;       // if CreateProcess

   CloseHandle(cWrite);
  CloseHandle(tRead);
end;


Мне не нужно считывание вывода приложения в консоль, а только нужно что бы запустив из моей программы некое приложение, дождаться его завершения и вывести мессагу что приложение завершило действие. При этом необходимо дальше работать с главной формой и с её элементами. Какой код можно на основе этого сделать без всего лишнего?


cruiser   (2008-10-27 22:23:00) [1]

Да. Почитал на просторах интернета http://vsokovikov.narod.ru/New_MSDN_API/Process_thread/fn_terminateprocess.htm
Думаю, что для моей задачи вполне можно испольовать данную функцию как TerminateProcess


Leonid Troyanovsky   (2008-10-27 22:16:00) [2]


> cruiser ©   (27.10.08 22:10) [19]

> private класса и запускаемое приложение теперь закрывается
> по
> TerminateProcess(ProcInfo.hProcess, 0)

Надеемся, что про UINT uExitCode читано, как, впрочем,
и все описалово TerminateProcess.

--
Regards, LVT.


cruiser   (2008-10-27 22:10:00) [3]

Всем большое спасибо. Ваши советы помогли. Сделал так, как и рекомендовали:
1. Сделал функцию Execandwait методом класса TForm1
2. Параметр ProcInfo: TProcessInformation объявил в разделе private класса и запускаемое приложение теперь закрывается по
TerminateProcess(ProcInfo.hProcess, 0)


clickmaker   (2008-10-27 18:02:00) [4]

> Извините, просто немного не могу понять как должен выглядить
> код.

а букварь почитать, прежде чем бездумно чужой код копипастить?


cruiser   (2008-10-27 18:00:00) [5]

Да - сейчас это функция. Т.е. при описании в разделе type её нужно указать? Извините, просто немного не могу понять как должен выглядить код.


Правильный$Вася   (2008-10-27 17:45:00) [6]


>  процедурой класса TForm1

методом, причем у тебя вроде ж как функция, а не процедура


cruiser   (2008-10-27 17:37:00) [7]

имел в виду процедурой класса TForm1


cruiser   (2008-10-27 17:36:00) [8]

Т.е. сделать процедурой TForm1? Правильно я понял?


Правильный$Вася   (2008-10-27 17:22:00) [9]


> Хотя бы кусочек кода как это сделать?

TForm1.ExecAndWait


cruiser   (2008-10-27 17:16:00) [10]


> Например, сделай его полем формы, а ExecAndWait - ее методом.


> > PI.hProcess определяется только в функии ExecAndWait
>
> сделай его методом класса формы, например


А можно подробнее? Хотя бы кусочек кода как это сделать? :)


Leonid Troyanovsky   (2008-10-27 16:04:00) [11]


> cruiser ©   (27.10.08 15:39) [8]

> Дело в том, что PI.hProcess определяется только в функии
> ExecAndWait. А как мне этот параметр сделать доступным для
> всей формы?

Например, сделай его полем формы, а ExecAndWait - ее методом.

--
Regards, LVT.


Правильный$Вася   (2008-10-27 16:03:00) [12]


> PI.hProcess определяется только в функии ExecAndWait

сделай его методом класса формы, например


clickmaker   (2008-10-27 15:44:00) [13]

> А как мне этот параметр сделать доступным для всей формы?

а сам-то как думаешь?
FProcessHandle := pi.hProcess


cruiser   (2008-10-27 15:39:00) [14]


> Мы думаем, что из-за того, что не создана CriticalSection.
>
> Кста, а зачем она здесь?

она создается в Tform.create. Попробую убрать из кода.

> TerminateProcess(PI.hProcess, 0)

Дело в том, что PI.hProcess определяется только в функии ExecAndWait. А как мне этот параметр сделать доступным для всей формы?


Leonid Troyanovsky   (2008-10-27 14:40:00) [15]


> cruiser ©   (26.10.08 17:51) [6]

> Но при закртыии программы (запускающей) выдается ошибка:
>  Access violation....
> Я так понимаю, что это из-за того, что не завершен созданный
> поток?

Мы думаем, что из-за того, что не создана CriticalSection.
Кста, а зачем она здесь?

> Подскажите как мне программно завершать правильно поток
> при закрытии запускающего приложения?

Правильно - никак. Поток завершится при выходе из функции потока.

> Т.е. мне надо при закрытии моего приложения или по нажатию
> кнопки на форме завершить запущенное приложение.

TerminateProcess(PI.hProcess, 0)

--
Regards, LVT.


cruiser   (2008-10-26 17:51:00) [16]

Спасибо. Разобрался. Сделал так:
procedure TForm1.Button1Click(Sender: TObject);
begin

 NewThread:=TNewThread.Create(true);
 NewThread.FreeOnTerminate:=true;
 NewThread.Priority:=tpLower;
 NewThread.Resume;

end;

procedure TNewThread.Execute;

begin
 CriticalSection.Enter;
 ExecAndWait (fp+'rar.exe', s, windows.SW_SHOWNORMAL );
 CriticalSection.Leave;
end;


Но при закртыии программы (запускающей) выдается ошибка: Access violation....
Я так понимаю, что это из-за того, что не завершен созданный поток? Подскажите как мне программно завершать правильно поток при закрытии запускающего приложения? Т.е. мне надо при закрытии моего приложения или по нажатию кнопки на форме завершить запущенное приложение.


{RASkov}   (2008-10-24 13:05:00) [17]

> [4] cruiser ©   (24.10.08 13:01)
> Т.е. тот код что приведен выше не подходит как исходная
> точка от которой отталкиваться?

К чему этот вопрос? В [3] вник или как?
В доп потоке делаешь запуск стороннего приложения и в нем ждешь окончания его работы, а основной поток работает....


cruiser   (2008-10-24 13:01:00) [18]

Да, я ошибся. Торопился с написанием  ответа. Т.е. тот код что приведен выше не подходит как исходная точка от которой отталкиваться?


Правильный$Вася   (2008-10-24 12:12:00) [19]


> в запускаемом, т.е. запустили приложение, а сами (наша программа)
> должна спокойно продолжать отвечать на клики

это запускающее, а не запускаемое

решается организацией запуска другого приложения в отдельной нити


cruiser   (2008-10-24 12:01:00) [20]

Извините за адрежку с ответом - в запускаемом, т.е. запустили приложение, а сами (наша программа) должна спокойно продолжать отвечать на клики, выбор элементов и т.п., т.е. на любые действия со стороны пользователя. Сейчас получается какой-то "висяк" - наше приложение зависает, пока не отработает запущенное.


Страницы:   1 2

Наверх

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