Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.075 c
15-1343236383
alexdn
2012-07-25 21:13
2013.03.22
Шрифт


15-1339432139
Лаура
2012-06-11 20:28
2013.03.22
Компоненты


2-1345387300
Владимир777
2012-08-19 18:41
2013.03.22
FTP-сервер не открывает сокет


15-1335703513
Vik
2012-04-29 16:45
2013.03.22
Создание кнопок.


15-1339736544
AV
2012-06-15 09:02
2013.03.22
с одной стороны - в отпуске. С другой - все неправильно





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский