Einzelnen Beitrag anzeigen

SebE

Registriert seit: 31. Jul 2004
Ort: Chemnitz
316 Beiträge
 
Delphi 7 Personal
 
#1

Problem mit Pipes und Threads

  Alt 30. Sep 2006, 16:59
Hi,
ich bastl'e nun schon seit Stunden an einem Program (Konsole), welches die Ausgabe eines fremden Programms zurückliefert, wenn man ihm ein Komando gibt.

Bsp: ich gebe dem "CMD" den Befehl "dir" -> es wird eine Liste angezeigt (mit Files/...)


ich habe einige Codes im Netz gefunden (nur OOP, ich will das aber in einer Konsole haben), aber es funzt bei mir nicht.

Hier der Quellcode:


Delphi-Quellcode:
program test;

{$APPTYPE CONSOLE}

uses
  Windows, Messages, SysUtils, StdCtrls,
  _system, _strings;

var
  cmd: String;

  buf: Array[1..5000] of CHAR;
  bytesRead: DWORD;

  isRunning: BOOL;

  process: DWORD;

  thread: DWORD;
  threadID: DWORD;

  inputPipeRead: DWORD;
  inputPipeWrite: DWORD;
  outputPipeRead: DWORD;
  outputPipeWrite: DWORD;

procedure pipeThreadProc;
var
  i: DWORD;
begin
while ReadFile(outputPipeRead, buf[1], 5000, bytesRead, nil) or isRunning do
  //wird nur einmal ausgeführt, wenn outputPipeWrite, dann geht es, aber buf ist leer
  begin
  if bytesRead > 0 then
  for i := 1 to bytesRead do
  Write(buf[i]);

  Sleep(500);
  Write(#7)
  end
end;




procedure writeToStdIn(const text: String);
var
  pos: DWORD;
  written: DWORD;
  res: BOOL;
  len: DWORD;
begin
if not (text = '') then
  begin
  pos := 1;

  len := DWORD(_strLen(text) + 2);

    repeat
    written := 0;

    res := WriteFile(inputPipeWrite, text[pos], len - pos + 1, written, nil);

    pos := pos + written
    until not (res) or (pos > len)
  end
end;




var
  startupInfo: TStartupInfo;//_STARTUPINFOA; //TStartupInfo;
  processInfo: TProcessInformation;
  securityAttr: TSECURITYATTRIBUTES;
  securityDesc: TSecurityDescriptor;

  i: DWORD;

begin
//Starten
FillChar(securityDesc, SizeOf(securityDesc), 0);
FillChar(ProcessInfo,SizeOf(TProcessInformation),0);

InitializeSecurityDescriptor(@securityDesc, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@securityDesc, true, nil, false);

with securityAttr do
  begin
  nLength := SizeOf(securityAttr);
  lpSecurityDescriptor := @securityDesc;
  bInheritHandle := true
  end;

process := 0;

if CreatePipe(inputPipeRead, inputPipeWrite, @securityAttr, 0) then //Input-Pipe
if CreatePipe(outputPipeRead, outputPipeWrite, @securityAttr, 0) then //Output-Pipe
  begin
  FillChar(startupInfo, SizeOf(startupInfo), 0);
  FillChar(processInfo, SizeOf(processInfo), 0);

  with startupInfo do
    begin
    cb := SizeOf(startupInfo);
    hStdOutput := outputPipeWrite;
    hStdInput := inputPipeRead;
    hStdError := outputPipeWrite;
    dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
    wShowWindow := SW_HIDE
    end;

  if CreateProcess(nil, PCHAR('Project2.exe'), @securityAttr, nil, true, 0, nil, nil,
    startupInfo, processInfo) then //statt "project2" könnte auch "cmd" stehen
    begin
    process := processInfo.hProcess;

    isRunning := true;
    thread := CreateThread(nil, 100, @pipeThreadProc, nil, 0, threadID);

    isRunning := not (thread = 0)
    end
  else
    begin
    CloseHandle(inputPipeRead);
    CloseHandle(inputPipeWrite);
    
    CloseHandle(outputPipeRead);
    CloseHandle(outputPipeWrite)
    end
  end
else
  begin
  CloseHandle(inputPipeRead);
  CloseHandle(inputPipeWrite)
  end;



  
//CMD lesen
cmd := '';

while not (cmd = '#exit') do
  begin
  ReadLn(cmd);
  writeToStdIn(cmd)
  end;




//Beenden
if not (process = 0) then
  begin
  isRunning := false;
  TerminateThread(thread, 0);

  CloseHandle(inputPipeRead);
  CloseHandle(inputPipeWrite);
  CloseHandle(outputPipeRead);
  CloseHandle(outputPipeWrite);

  TerminateProcess(process, 0); //CMD-Fenster schließen
  CloseHandle(process);

  process := 0
  end;

ReadLn
end.
Was muss ich ändern, damit es geht?
Sebastian
  Mit Zitat antworten Zitat