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

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

Не читает вывод из консоли [D7]


Страницы:   1 2 3

mamedovvms ©   (2009-08-25 08:45:00) 

nit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}
procedure RunDosInMemo(DosApp:String;AMemo:TMemo) ;
const
  ReadBuffer = 512;
var
l:boolean;

Security : TSecurityAttributes;
ReadPipe,WritePipe : THandle;
start : TStartUpInfo;
ProcessInfo : TProcessInformation;
Buffer : Pchar;
BytesRead : DWord;
Apprunning : DWord;
x : Integer;
MyStr : String;
begin

  x := 0;
  With Security do
  begin
   Security.nlength := SizeOf(TSecurityAttributes) ;
   Security.binherithandle := true;
   Security.lpsecuritydescriptor := nil;
  end;

  if Createpipe (ReadPipe, WritePipe,
                 @Security, 0) then
  begin
    Buffer := AllocMem(ReadBuffer + 1) ;
    FillChar(Start,Sizeof(Start),#0) ;
    start.cb := SizeOf(STARTUPINFO) ;
    start.hStdOutput := WritePipe;
    start.hStdInput := ReadPipe;
    start.dwFlags := STARTF_USESTDHANDLES ;
    start.wShowWindow := SW_SHOW;

    if CreateProcess(nil,
          PChar(DosApp),
          @Security,
          @Security,
          true,
          NORMAL_PRIORITY_CLASS,
          nil,
          nil,
          start,
          ProcessInfo)
    then
    begin
    CloseHandle(WritePipe) ;
        WaitForSingleObject(ProcessInfo.hProcess, INFINITE);

        BytesRead := 0;
        l:=ReadFile(start.hStdInput,Buffer[0],ReadBuffer,BytesRead,nil) ;

        ShowMessage(Buffer);
        Buffer[BytesRead]:= #0;
        OemToAnsi(Buffer,Buffer) ;

        AMemo.Lines.Add(MyStr);
        AMemo.Refresh;
        Application.ProcessMessages;

      FreeMem(Buffer) ;
      CloseHandle(ProcessInfo.hProcess) ;
      CloseHandle(ProcessInfo.hThread) ;
      CloseHandle(ReadPipe) ;

    end;

  end;

 end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  RunDosInMemo('c:\cons.exe',memo1) ;
end;

end.
что сделано не так??? может кто знает???
да к стати консольная программа cons.exe просто выводит на экран строку 12345678910, написана на pascal может я что то не понял и нельзя так делать????


Leonid Troyanovsky   (2009-08-26 11:46:00) [21]


> mamedovvms ©   (26.08.09 11:35) [34]

> s := Format('"1.exe" "2.txt"', [FullPathNameExeFile, FullPathNameParamFile]);

Здесь самодеятельность не нужна, здесь требуется сосредоточится
на именах файлов вместе с полными путями к ним.

И не надо повторно постить RunDosInMemo, от нее нас тошнит.

Гм.. я про напильник, а руки, небось к топору привыкли.

--
Regards, LVT.


mamedovvms   (2009-08-26 11:35:00) [22]

то есть должно получиться так ???
procedure RunDosInMemo(DosApp:String;AMemo:TMemo) ;
var
Security : TSecurityAttributes;
ReadPipe,WritePipe : THandle;
start : TStartUpInfo;
ProcessInfo : TProcessInformation;
BytesRead : DWord;
s: String;
buf : array [0..4095] of Char;
begin

With Security do
begin
Security.nlength := SizeOf(TSecurityAttributes) ;
Security.binherithandle := true;
Security.lpsecuritydescriptor := nil;
end;

if Createpipe (ReadPipe, WritePipe,
              @Security, 0) then
begin
 ZeroMemory(@start, SizeOf(TStartupInfo)); ;
 start.cb := SizeOf(STARTUPINFO) ;
 start.hStdOutput := WritePipe;
 start.hStdError := WritePipe;

 start.dwFlags := STARTF_USESTDHANDLES ;
 start.wShowWindow := SW_SHOW;

 if CreateProcess(nil,
       PChar(DosApp),
       nil,
       nil,
       true,
       NORMAL_PRIORITY_CLASS,
       nil,
       nil,
       start,
       ProcessInfo)
 then
 begin
 CloseHandle(WritePipe) ;
 CloseHandle(ProcessInfo.hThread) ;

 repeat

   if not ReadFile(ReadPipe, buf[0], SizeOf(buf), BytesRead,nil) then
     Break;
   SetString(s, buf, BytesRead);
   AMemo.SelText := s;
 until (BytesRead = 0) and
       (WaitForSingleObject(ProcessInfo.hProcess, 0) = WAIT_OBJECT_0);

   CloseHandle(ProcessInfo.hProcess) ;

   CloseHandle(ReadPipe) ;

 end;

end;

end;

procedure TForm1.Button1Click(Sender: TObject);
var s:string;
begin

s := Format('"1.exe" "2.txt"', [FullPathNameExeFile, FullPathNameParamFile]);
RunDOSinMemo(s, memo1);
end;


Leonid Troyanovsky   (2009-08-26 11:25:00) [23]


> mamedovvms ©   (26.08.09 10:41) [32]

> RunDOSinMemo('ping localhost', memo1);


var
 s: String;

s := Format('"%s" "%s"', [FullPathNameExeFile, FullPathNameParamFile]);
RunDOSinMemo(s, memo1);

--
Regards, LVT.


mamedovvms   (2009-08-26 10:41:00) [24]

то есть мне не понятно где в моем коде это надо прописать здесь
if CreateProcess(nil,
       PChar(DosApp),
       nil,
       nil,
       true,
       NORMAL_PRIORITY_CLASS,
       nil,
       nil,
       start,
       ProcessInfo)

или
RunDOSinMemo('ping localhost', memo1);
и как
AnsiQuotedStr ("2.txt"); так%


mamedovvms   (2009-08-26 10:35:00) [25]

то есть где мне надо это приписать , если не сложно объясните поконкретнее


Leonid Troyanovsky   (2009-08-26 10:31:00) [26]


> mamedovvms ©   (26.08.09 10:25) [29]

> это приложение считывает данные которые ему надо из файла
> 2.txt как при запуске 1.exe передать параметр 2.txt

В двойных кавычках. see AnsiQuotedStr function.
Параметры разделяются пробелом.

--
Regards, LVT.


mamedovvms   (2009-08-26 10:25:00) [27]

ладно, а подскажи пожалуйста , вот у меня есть консольное приложение 1.exe
это приложение считывает данные которые ему надо из файла 2.txt как при запуске 1.exe передать параметр 2.txt


Leonid Troyanovsky   (2009-08-26 10:09:00) [28]


> mamedovvms ©   (26.08.09 09:57) [27]

> раз, а во вторых я думаю лучше бы подсказали что и как надо
> сделать

Примерно так:

http://groups.google.com/group/fido7.ru.delphi/msg/b67d07fe0087e067

Но, и там ошибок хватает.
Главная, BeginThread instead CreateThread, ну и там по-мелочи еще.
Но, за основу проще взять и подработать напильником.

--
Regards, LVT.


mamedovvms   (2009-08-26 09:57:00) [29]

ну попробывать то конечно можно но как бы не советовал это раз, а во вторых я думаю лучше бы подсказали что и как надо сделать


Leonid Troyanovsky   (2009-08-26 09:37:00) [30]


> mamedovvms ©   (26.08.09 07:01) [25]

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


procedure RunDosInMemo(DosApp:String;AMemo:TMemo) ;
var
Security : TSecurityAttributes;
ReadPipe,WritePipe : THandle;
start : TStartUpInfo;
ProcessInfo : TProcessInformation;
BytesRead : DWord;
s: String;
buf : array [0..4095] of Char;
begin

With Security do
begin
 Security.nlength := SizeOf(TSecurityAttributes) ;
 Security.binherithandle := true;
 Security.lpsecuritydescriptor := nil;
end;

if Createpipe (ReadPipe, WritePipe,
               @Security, 0) then
begin
  ZeroMemory(@start, SizeOf(TStartupInfo)); ;
  start.cb := SizeOf(STARTUPINFO) ;
  start.hStdOutput := WritePipe;
  start.hStdError := WritePipe;

  start.dwFlags := STARTF_USESTDHANDLES ;
  start.wShowWindow := SW_SHOW;

  if CreateProcess(nil,
        PChar(DosApp),
        nil,
        nil,
        true,
        NORMAL_PRIORITY_CLASS,
        nil,
        nil,
        start,
        ProcessInfo)
  then
  begin
  CloseHandle(WritePipe) ;
  CloseHandle(ProcessInfo.hThread) ;

  repeat

    if not ReadFile(ReadPipe, buf[0], SizeOf(buf), BytesRead,nil) then
      Break;
    SetString(s, buf, BytesRead);
    AMemo.SelText := s;
  until (BytesRead = 0) and
        (WaitForSingleObject(ProcessInfo.hProcess, 0) = WAIT_OBJECT_0);

    CloseHandle(ProcessInfo.hProcess) ;

    CloseHandle(ReadPipe) ;

  end;

end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 RunDOSinMemo('ping localhost', memo1);
end;

Но, во-ще, за такой код убивать надо, из рогатки.

--
Regards, LVT.


mamedovvms   (2009-08-26 07:01:00) [31]

переделал вот так но почему то все равно мне выводит огромное количество  строк, хотя должно выводить как я понимаю только одну строку, что опять сделал не так уже мозг кипит , не могу понять
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
  Button1: TButton;
  Memo1: TMemo;
  procedure Button1Click(Sender: TObject);
private
  { Private declarations }
public
  { Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure RunDosInMemo(DosApp:String;AMemo:TMemo) ;
var
l:boolean;
dwAvail:Cardinal;
Security : TSecurityAttributes;
ReadPipe,WritePipe : THandle;
start : TStartUpInfo;
ProcessInfo : TProcessInformation;
BytesRead : DWord;
Apprunning : DWord;
x : Integer;
MyStr,s : String;
begin

 x := 0;
 With Security do
 begin
  Security.nlength := SizeOf(TSecurityAttributes) ;
  Security.binherithandle := true;
  Security.lpsecuritydescriptor := nil;
 end;

 if Createpipe (ReadPipe, WritePipe,
                @Security, 0) then
 begin
   ZeroMemory(@start, SizeOf(TStartupInfo)); ;
   start.cb := SizeOf(STARTUPINFO) ;
   start.hStdOutput := WritePipe;
   start.hStdInput := 0;
   start.dwFlags := STARTF_USESTDHANDLES ;
   start.wShowWindow := SW_SHOW;

   if CreateProcess(nil,
         PChar(DosApp),
         @Security,
         @Security,
         true,
         NORMAL_PRIORITY_CLASS,
         nil,
         nil,
         start,
         ProcessInfo)
   then
   begin
   CloseHandle(WritePipe) ;
   repeat

       PeekNamedPipe(ReadPipe, nil, 0, nil, @dwAvail, nil);
       if dwAvail>0 then
        begin
         SetLength(S, dwAvail);

        ReadFile(ReadPipe,PChar(S)^, Length(S), BytesRead,nil);
         ShowMessage(s);
         Break;
        end;

   until(dwAvail>0);
     CloseHandle(ProcessInfo.hProcess) ;
     CloseHandle(ProcessInfo.hThread) ;
     CloseHandle(ReadPipe) ;

  {   TerminateProcess(pi.hProcess,NO_ERROR);}
   end;

 end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 RunDosInMemo('c:\1\mxi-7.1-eu.exe c:\1\client.ini',memo1) ;
end;

end.


mamedovvms   (2009-08-25 14:52:00) [32]

почему долго не считывает, а потом выдает целую кучу, что я опять не так сделал вроде уже все посмотрел что бы было как надо


mamedovvms   (2009-08-25 14:38:00) [33]

да нет просто сразу как только программа запустилась уже есть что считывать но она почему то не читает, даже использование PeekNamedPipe почему то ничего не дает, не знаю что не так


Сергей М.   (2009-08-25 14:15:00) [34]

Хочешь сказать, что PeekNamedPipe сказал тебе, что имеются к чтению 100 байт, ты тут же вызвал ReadFile, заказав к чтению 100 байт - и ReadFile при  этом выполняется несколько минут ?


mamedovvms   (2009-08-25 14:04:00) [35]

да не понял ты меня, что ты хочешь сказать что просто чтение , когда есть что читать может длиться несколько минут???


Сергей М.   (2009-08-25 13:47:00) [36]

Мало ли что тебе хочется)
Чужой процесс волен выводить 3 символа целый час, а следующие 97 символов за десятую секунды.
Хочешь получить свои 100 "все сразу", за один вызов ReadFile ? Придется ждать час с лишним ? Не хочешь при этом "висеть" ? Читай пайп в доп.потоке.


mamedovvms   (2009-08-25 13:38:00) [37]

ну а если вот мне хочется что бы выводилось по 100 знаков, ну вот хочется


Сергей М.   (2009-08-25 13:28:00) [38]

А что собссно мешает дождаться завершения процесса и прочитать роман целиком ?


mamedovvms   (2009-08-25 13:21:00) [39]

я пробывал вместо 512 ставить 8 но процесс быстрее не становиться , может надо еще  при создании пайпа поставить?
Createpipe (ReadPipe, WritePipe, @Security, 0)


Сергей М.   (2009-08-25 13:14:00) [40]


> ожно было бы считать уже хотябы пару страниц


Можно и одну строку и даже одну букву читать.
Но ты-то целый роман запросил:

ReadBuffer = 512;

Эти этот роман в 512 символов порожденный тобой процесс волен выводить столь долго, сколь ему вздумается.

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


Страницы:   1 2 3

Наверх

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