2011-03-24 7 views
0

Можно создать дубликат:
How to read from an external console application?встроенные консольные приложения в Delphi

У меня есть консольное приложение, третья вечеринка

Я хочу, чтобы выполнить его во время выполнения сформировать приложение Дельфах.

об исполнении

окно консоли приложения должны быть hidden.and все сообщения от консольного приложения должны быть напечатаны в контроле моего приложения (текстовое поле памятки и т.д.)

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

Может кто-нибудь помочь мне сделать это

ответ

0

Смотрите это answer и this один.

Zarko написал об этом на Delphi.about.com.

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

Чтобы сделать ответ в двух направлениях, как вы его просите, очень сложно, и я не знаю никого, кто полностью реализовал «командный интерпретатор» или «режим терминала» в delphi.

Я поместил код Златко в Delphi XE (также работает в 2010 году) here.

+0

+1 для первого ответа – VibeeshanRC

+0

Anonymous downvoter, прокомментируйте, пожалуйста, почему это может быть улучшено? –

3

Это позволит вам запускать и получать информацию обратно из приложения консоли (DOS) в TRichEdit. Он не позволяет вводить текст после запуска приложения, но, возможно, это даст вам отправную точку. (Оригинальный код из группы новостей поста, написанного доктором Питером Ниже из TeamB.)

procedure TFMainForm.RunDosInMemo(const App: String; AMemo: TRichEdit); 
const 
    ReadBuffer = 2400; 
var 
    Security : TSecurityAttributes; 
    StdInPipeR, StdInPipeW : THandle; 
    StdOutPipeR, StdOutPipeW : THandle; 
    StartInfo : TStartUpInfo; 
    ProcessInfo : TProcessInformation; 
    Buffer : PByte; 
    BytesAvailable, BytesRead : DWord; 
    sDosApp: String; 
    sData: RawByteString; 
begin 
    sDosApp := DosApp; 
    UniqueString(sDosApp); 

    with Security do begin 
    nLength := SizeOf(TSecurityAttributes); 
    bInheritHandle := True; 
    lpSecurityDescriptor := nil; 
    end; 

    if CreatePipe(StdInPipeR, StdInPipeW, @Security, 0) then 
    try 

    SetHandleInformation(StdInPipeW, HANDLE_FLAG_INHERIT, 0); 
    if CreatePipe(StdOutPipeR, StdOutPipeW, @Security, 0) then 
    try 
     SetHandleInformation(StdOutPipeR, HANDLE_FLAG_INHERIT, 0); 
     GetMem(Buffer, ReadBuffer); 
     try 
     ZeroMemory(@StartInfo, SizeOf(StartInfo)); 
     StartInfo.cb := SizeOf(StartInfo); 
     StartInfo.hStdOutput := StdOutPipeW; 
     StartInfo.hStdInput := StdInPipeR; 
     StartInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; 
     StartInfo.wShowWindow := SW_HIDE; 

     if CreateProcess(nil, 
         PChar(sDosApp), 
         nil, 
         nil, 
         True, 
         NORMAL_PRIORITY_CLASS, 
         nil, 
         nil, 
         StartInfo, 
         ProcessInfo) then 
      try 
      while WaitForSingleObject(ProcessInfo.hProcess, 500) <> WAIT_TIMEOUT do 
       Application.ProcessMessages; 
      while PeekNamedPipe(StdOutPipeR, nil, 0, nil, BytesAvailable, nil) do 
      begin 
       if BytesAvailable < 1 then 
       Break; 
       if BytesAvailable > ReadBuffer then 
       BytesAvailable := ReadBuffer; 
       if not ReadFile(StdOutPipeR, 
           Buffer[0], 
           BytesAvailable, 
           BytesRead, 
           nil) then 
       Break; 
       SetString(sData, PAnsiChar(Buffer), BytesRead); 
       // assign an appropriate codepage for the output data: 
       // 0 for default Ansi, 1252 or 20157 for ASCII, 1200 for 
       // Unicode, etc... 
       SetCodePage(sData, ...); 
       // this is faster and more efficient than reading/writing the 
       // Text property directly... 
       AMemo.SelStart := AMemo.GetTextLen; 
       AMemo.SelLength := 0; 
       AMemo.SelText := sData; 
      end; 
      finally 
      CloseHandle(ProcessInfo.hThread); 
      CloseHandle(ProcessInfo.hProcess); 
      end; 
     finally 
     FreeMem(Buffer); 
     end; 
    finally 
     CloseHandle(StdOutPipeR); 
     CloseHandle(StdOutPipeW); 
    end; 
    finally 
    CloseHandle(StdInPipeR); 
    CloseHandle(StdInPipeW); 
    end; 
end; 
Смежные вопросы