Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail


Донат для форума - использовать для поднятия настроения себе и модераторам

А ещё здесь можно купить рекламу за 25 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru

Ответ
 
Опции темы
Старый 06.11.2007, 13:51   #1
Sashunya
Пользователь
 
Регистрация: 28.08.2007
Сообщений: 11
Репутация: 10
По умолчанию Прибить Create Process с содержимым

Привет всем!
Короче проблема следующая: есть кусок кода, кот. запускает консольную программу (без окна) через Pipe, CreateProcess. Потом все данные с этой программы берет и кидает в Memo, а потом программу, эту консольную нужно закрыть. Мое приложение закрывать не нужно.

Вопрос как? Подскажите плиз, просто с Пайпами никогда не сталкивался.

Код:
var
  Form1: TForm1;
  FChildStdinWr: THandle;
//    PI: TProcessInformation;
  tRead, cWrite, dwAvail: cardinal;
  SA: TSecurityAttributes;
  PI: TProcessInformation;
  SI: TStartupInfo;
  sBuff: THandleStream;
  StringBuf: TStringList;
  ret : Cardinal;
  m : TMemoryStream;
  fla : boolean;


implementation

{$R *.dfm}


Procedure RunAny(CommandLine: string; Str: TStrings);

begin
  //Инициализация
  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;
  SI.hStdInput:= FChildStdinWr;
  //Стартуем процесс...
  if CreateProcess(nil, PChar(CommandLine), nil, nil , True, 0, nil, nil, SI, PI)
  then begin
      Str.Clear();
      sBuff := THandleStream.Create(tRead);
      StringBuf := TStringList.Create();
      m := TMemoryStream.Create;
      repeat
        //Ждем N-дцать минут
        Ret := WaitForSingleObject(PI.hProcess, 100);
         application.ProcessMessages;
          StringBuf.Clear();
        if sBuff.Size > 0 then
        begin
          fla := (m.Size > 0) and not (PByteArray(m.Memory)^[m.Size - 1] in [13, 10]);
          m.Size := 0;
          m.LoadFromStream(sBuff);
          m.Position := 0;
          StringBuf.LoadFromStream(m); //Помещаем блок в буфер
          if StringBuf.Count > 0 then
          begin
            //Склеиваем разорванную строку
            if (Str.Count > 0) and fla then
            begin
              StringBuf.Strings[0] := Str.Strings[Str.Count-1]+StringBuf.Strings[0];
              Str.Delete(Str.Count-1);
            end;
          end;
          //Добавляем блок из буфера
          Str.AddStrings(StringBuf);
        end;
        //не пуст ли pipe ?
        //PeekNamedPipe(tRead, nil, 0, nil, @dwAvail, nil);

    until (Ret <> WAIT_TIMEOUT);
      m.Free;
      CloseHandle(PI.hProcess);
      CloseHandle(PI.hThread);
  end;       // if CreateProcess
  CloseHandle(tRead);
  CloseHandle(cWrite);
end;



procedure TForm1.Button1Click(Sender: TObject);
begin
runAny('это моя программа.exe',memo1.Lines);
end;

// пробовал это - не помогает


// прибить процесс.
procedure TForm1.Button2Click(Sender: TObject);
var tmp: Thandle;
begin
DuplicateHandle(GetCurrentProcess,F ChildStdinWr,GetCurrentProcess,@Tmp ,0,False,DUPLICATE_SAME_ACCESS);
CloseHandle(FChildStdinWr);
FChildStdinWr:=Tmp;
end;

Последний раз редактировалось rpy3uH; 30.07.2008 в 11:23.
Sashunya вне форума   Ответить с цитированием
Старый 06.11.2007, 14:19   #2
Stilet
Белик Виталий :)
Профессионал
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Адрес: Украина, Донецкая область, г. Краматорск
Сообщений: 57,815
Репутация: 6850
По умолчанию

Ну я так понимаю TerminateProcess поможет
Stilet вне форума   Ответить с цитированием
Старый 06.11.2007, 14:32   #3
Sashunya
Пользователь
 
Регистрация: 28.08.2007
Сообщений: 11
Репутация: 10
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Ну я так понимаю TerminateProcess поможет
Не поможет. Он программу, запущенную приложением не закрывает. И даже не дает закрыть мою исходную программу. Пробовал через FindWindow так у программы нет окна. Короче не знаю. Но правда если программе послать Ctrl+C то она прибьется сама. Может в эту сторону смотреть. Тогда встречный вопрос: как прикрутить писальный Пайп к моему коду. Если можно с примерчиком плиз.
Sashunya вне форума   Ответить с цитированием
Старый 06.11.2007, 16:24   #4
Stilet
Белик Виталий :)
Профессионал
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Адрес: Украина, Донецкая область, г. Краматорск
Сообщений: 57,815
Репутация: 6850
По умолчанию

Цитата:
Он программу, запущенную приложением не закрывает
Вообще то должен закрывать. А как ты им рулишь?
Stilet вне форума   Ответить с цитированием
Старый 06.11.2007, 17:23   #5
Sashunya
Пользователь
 
Регистрация: 28.08.2007
Сообщений: 11
Репутация: 10
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Вообще то должен закрывать. А как ты им рулишь?
Да сам процесс закрывается, но ехешник, запущенный эти процессом остается в памяти. Вот в чем загвоздка. Короче нашел готовый пример, кот. прибивает процесс и все работает корректно:
Я думаю, ты не это имел ввиду?

function KillTask(ExeFileName: string): Integer;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
Result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNA PPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

while Integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProces sEntry32.szExeFile)) =
UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFil e) =
UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(
OpenProcess(PROCESS_TERMINATE,
BOOL(0),
FProcessEntry32.th32ProcessID),
0));
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;

// прибить процесс.
procedure TForm1.Button2Click(Sender: TObject);
begin
KillTask('моя программа.exe');
end;

Это корректно вообще? Просто подозрительно гладко заработало, теперь можно спокойно парсить строки.
Sashunya вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
kill process const Общие вопросы C/C++ 2 28.08.2008 19:11
Выбор компонента для работы с содержимым текстовых файлов[Delphi] sergey31 Помощь студентам 2 28.08.2008 16:53
Create DLL Altera Свободное общение 4 12.02.2008 04:28
скопировать папку со всем её содержимым Tech07 Общие вопросы Delphi 8 02.12.2007 13:06
Проблемы с internet-ом (Generic Host Process for Win32 Services), help young_W Операционные системы общие вопросы 4 06.11.2007 23:30


13:05.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.