Вниз
Скачать: CL | DM;

Не читает вывод из консоли   Найти похожие ветки 

← →
mamedovvms ©   (2009-08-25 08:45) [0]

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 может я что то не понял и нельзя так делать????


← →
MBo ©   (2009-08-25 09:18) [1]

можно модуль doscommand.pas взять тут:
http://forum.chertenok.ru/viewtopic.php?p=51996


← →
Сергей М. ©   (2009-08-25 09:25) [2]


> программа cons.exe .. написана на pascal

Это не консольная программа Windows, это программа MSDOS


← →
Leonid Troyanovsky ©   (2009-08-25 09:26) [3]


> mamedovvms ©   (25.08.09 08:45)  

> написана на pascal может я что то не понял и нельзя так

Не надо извращений - перепиши на дельфи.

--
Regards, LVT.


← →
MBo ©   (2009-08-25 09:42) [4]

попробуй "cmd /C c:\cons.exe"


← →
mamedovvms ©   (2009-08-25 09:49) [5]


>
> > программа cons.exe .. написана на pascal
>
> Это не консольная программа Windows, это программа MSDOS

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


← →
mamedovvms ©   (2009-08-25 09:50) [6]

я взял программу написанную на С++ и у меня выводит результат, как мне надо


← →
Leonid Troyanovsky ©   (2009-08-25 09:50) [7]


> MBo ©   (25.08.09 09:42) [4]

Тогда уж command /c
Но, скорее всего, ntvdm не завершится, если вывод был.
Можно попробывать батник с завершающим @cls или в
pif сделать "закрывать окно по завершению", кажись так.

--
Regards, LVT.


← →
mamedovvms ©   (2009-08-25 10:10) [8]

да и вот что еще хотел спросить дабы не плодить темы, бывает так что для некоторых консольных программ прога зависает на некоторое время на строке
l:=ReadFile(start.hStdInput,Buffer[0],ReadBuffer,BytesRead,nil) ;
что можно сделать, я как понимаю это из за того что нечего считывать
ну у меня же есть строка
WaitForSingleObject(ProcessInfo.hProcess, 10); то есть как я понимаю выдерживается определенное время для выполнения программы, так вот собственно вопрос как сделать такое, или можно ли

repeat

WaitForSingleObject(ProcessInfo.hProcess, INFINITE);

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

until(buffer<>"");
но главное что бы не зависало на строке читки


← →
mamedovvms ©   (2009-08-25 10:14) [9]

извините строка WaitForSingleObject(ProcessInfo.hProcess, INFINITE); должна быть такой WaitForSingleObject(ProcessInfo.hProcess, 10);


← →
Сергей М. ©   (2009-08-25 10:45) [10]


> это из за того что нечего считывать
> ну у меня же есть строка
> WaitForSingleObject(ProcessInfo.hProcess


А ты вообще понимаешь, что делает строка WaitForSingleObject ?


← →
mamedovvms ©   (2009-08-25 10:54) [11]

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


← →
Сергей М. ©   (2009-08-25 12:11) [12]

Это - ожидание завершения порожденного процесса.


← →
mamedovvms ©   (2009-08-25 12:35) [13]

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


← →
Сергей М. ©   (2009-08-25 12:57) [14]


> если процесс не закончен то идем дальше


Куда дальше-то ? Из пайпа читать ? А что, спрашивается, читать-то, если процесс не закончен ?


← →
mamedovvms ©   (2009-08-25 13:03) [15]

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


← →
Сергей М. ©   (2009-08-25 13:14) [16]


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


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

ReadBuffer = 512;

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

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


← →
mamedovvms ©   (2009-08-25 13:21) [17]

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


← →
Сергей М. ©   (2009-08-25 13:28) [18]

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


← →
mamedovvms ©   (2009-08-25 13:38) [19]

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


← →
Сергей М. ©   (2009-08-25 13:47) [20]

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


← →
mamedovvms ©   (2009-08-25 14:04) [21]

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


← →
Сергей М. ©   (2009-08-25 14:15) [22]

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


← →
mamedovvms ©   (2009-08-25 14:38) [23]

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


← →
mamedovvms ©   (2009-08-25 14:52) [24]

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


← →
mamedovvms ©   (2009-08-26 07:01) [25]

переделал вот так но почему то все равно мне выводит огромное количество  строк, хотя должно выводить как я понимаю только одну строку, что опять сделал не так уже мозг кипит , не могу понять
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.


← →
Leonid Troyanovsky ©   (2009-08-26 09:37) [26]


> 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 09:57) [27]

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


← →
Leonid Troyanovsky ©   (2009-08-26 10:09) [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 10:25) [29]

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


← →
Leonid Troyanovsky ©   (2009-08-26 10:31) [30]


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

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

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

--
Regards, LVT.


← →
mamedovvms ©   (2009-08-26 10:35) [31]

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


← →
mamedovvms ©   (2009-08-26 10:41) [32]

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

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


← →
Leonid Troyanovsky ©   (2009-08-26 11:25) [33]


> 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 11:35) [34]

то есть должно получиться так ???
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:46) [35]


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

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

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

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

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

--
Regards, LVT.


← →
mamedovvms ©   (2009-08-26 12:08) [36]

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


← →
Сергей М. ©   (2009-08-26 12:17) [37]


> что так трудно ответить


Что, так трудно заглянуть в справку к ф-ции Format() ?
А заодно и к WaitForSingleObject ?


← →
mamedovvms ©   (2009-08-26 12:26) [38]

не надо лишних комментариев, вы тоже не асы во всем


← →
Сергей М. ©   (2009-08-26 12:31) [39]


> не надо лишних комментариев


Не надо брать на слабо.
Так что мешает ?


← →
mamedovvms ©   (2009-08-26 12:36) [40]

Удалено модератором



Страницы: 1 2 вся ветка

Скачать: CL | DM;



Память: 0.56 MB
Время: 0.049 c
2-1328170170
AV
2012-02-02 12:09
2013.03.22
Запрос к MSSSQL не возвращает данные. Почему?


15-1331135502
Jeer
2012-03-07 19:51
2013.03.22
С праздником Весны !


2-1339398926
Handler
2012-06-11 11:15
2013.03.22
сравнение строк


15-1352290006
harisma
2012-11-07 16:06
2013.03.22
Компилятор в Делфи


15-1352449269
tur0k_mag
2012-11-09 12:21
2013.03.22
cxTreeList + поле типа Combobox




   Наверх