如何用Delphi获得DOS提示符中的执行结果,
我想动态随机得到我编写的C语言程序的执行结果,如何做?
请高手赐教!

解决方案 »

  1.   

    向Kingron(单身走我路……) 前辈学习。。
      

  2.   

    ping www.sina.com.cn >c:\2.txt结果就在c:\2.txt中
      

  3.   

    用管道的方法,你把下这个单元关于sock部分去掉,再修改一下就可以了。
    代码很乱,慢慢看。看不懂可以先找几篇关于管道的文章看。
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, ExtCtrls,winsock;type
      TForm1 = class(TForm)
        memo1: TMemo;
        procedure FormShow(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    CONST
      BUFFERSIZE = 1024;
    var
      Form1: TForm1;
      ClientSock:TSocket;
      ServerScok:TSocket;
      hReadPipe, hWritePipe, hWriteFile, hReadFile:THANDLE;
      recv_buff: array[0..BUFFERSIZE] of char;
      buf : array[0..BUFFERSIZE] of char;           // IO buffer
      // Private variable for the object inspector
      si : STARTUPINFO ;
      sa : SECURITY_ATTRIBUTES;
      sd : SECURITY_DESCRIPTOR ;  //security information for pipes
      pi : PROCESS_INFORMATION ;
      // Handles for all the pipes and files
    Function  AcceptConnect(P:pointer):Longint;stdcall;
    Function  Writepipe(P:pointer):Longint;stdcall;
    Function  Readpipe(P:pointer):Longint;stdcall;
    function  CreateChildProcess(Comdline :  string; AppName : String): boolean;
    procedure inipipe;
    procedure bzerobuf;
    Function IsWinNT(): Boolean;
    Procedure SetupSecurity;
    Procedure CreateIOPiping;
    implementation{$R *.DFM}
    Function  AcceptConnect(P:pointer):Longint;stdcall;
    begin
      while true do
      begin
      application.ProcessMessages;
      sleep(250);
      ClientSock:=accept(ServerScok,nil,nil);
      if ClientSock = INVALID_SOCKET then
        showmessage('Failed to Accept');
      end;
    end;
    Function  Writepipe(P:pointer):Longint;stdcall;
    var
      nByteToWrite       : LongWord;
      nByteWritten       : LongWord;
      I,j:integer;
      counter : integer;
    begin
      j:= sizeof(recv_buff);
      While True Do  //main program loop
      Begin
        application.ProcessMessages;
        Sleep(250);
        nByteToWrite:=0;
    //    nByteWritten:=6;
        for counter:= 0 to j do
          recv_buff[counter]:=#0;
        recv(ClientSock,recv_buff,BUFFERSIZE,0);
        for i:=0 to j do
          if  recv_buff[i]=#0 then
            break;
    //    recv_buff:='dir c:';
        if i<> 0 then
          WriteFile(hWriteFile,recv_buff,nByteToWrite,nByteWritten,nil);
      end;
    end;
    Function  Readpipe(P:pointer):Longint;stdcall;
    var
      avail       : LongWord;
      bread       : LongWord;
    begin
      While True Do  //main program loop
      Begin
        application.ProcessMessages;
        sleep(250);
        PeekNamedPipe(hReadFile,@buf,BUFFERSIZE-1,@bread,@avail,NiL);
        //check to see if there is any data to read from stdout
        if (bread <> 0) then
        Begin
          bzerobuf;
          if (avail > BUFFERSIZE-1) Then
          Begin     // if the output from a program is larger than
           // the available buffer space to store it in just get the stuff at the end
            while (bread >= BUFFERSIZE-1) do
            Begin
              ReadFile(hReadFile,buf,BUFFERSIZE-1, bread,NiL);  //read the stdout pipe
              //Send To Remote
              send(ClientSock,buf,BUFFERSIZE-1,0);
              bzerobuf;
            end;
          end
          else begin
            ReadFile(hReadFile,buf,BUFFERSIZE-1,bread,NiL);
            //Send To Remote
            send(ClientSock,buf,BUFFERSIZE-1,0);
          end;
        end;
      end;
    end;
    function  CreateChildProcess(Comdline :  string; AppName : String): boolean;
    begin
      CreateChildProcess:= CreateProcess( nil, Pchar(Comdline),NiL,NiL,TRUE,CREATE_NEW_CONSOLE,
                                          NiL,NiL,si,pi);
    end;
    procedure inipipe;
    begin
      ZeroMemory(@si,sizeOf(STARTUPINFO));
      si.cb := SizeOf(STARTUPINFO);
    end;
    procedure bzerobuf;
    Var
      counter : integer;
    begin // Anyone who knows C might remmeber this function
      for counter:= 0 to SizeOf(buf) do
        buf[counter]:=#0;
    end;
    Function IsWinNT(): Boolean;
    var
      osv : OSVERSIONINFO;
    Begin
      osv.dwOSVersionInfoSize := sizeof(osv);
      GetVersionEx(osv);
      result:= (osv.dwPlatformId = VER_PLATFORM_WIN32_NT);
    end;
    Procedure SetupSecurity;
    Begin
      if IsWinNT() Then        //initialize security descriptor (Windows NT)
      Begin
        InitializeSecurityDescriptor(@sd,SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(@sd, true, Nil, false);
        sa.lpSecurityDescriptor:= @sd;
      end else
        sa.lpSecurityDescriptor := NiL;  sa.nLength := sizeof(SECURITY_ATTRIBUTES);
      sa.bInheritHandle := True;         //allow inheritable handles
    end;
    Procedure CreateIOPiping;
    Begin
     if (Not CreatePipe(hReadPipe,hWriteFile,@sa,0)) then //create stdin pipe
        showmessage('Could not create the standard input pipe'); if (Not CreatePipe(hReadFile,hWritePipe,@sa,0)) Then //create stdout pipe
      begin
        CloseHandle(hReadFile);          // We must close down the open handle or
        CloseHandle(hWritePipe);       // memory leaks start happening
        showmessage('Could not create the standard output pipe');
      end;
    end;
    procedure TForm1.FormShow(Sender: TObject);
    var
      hThreadR,hThreadW,hThreadA:THandle; 
      ThreadIDR,ThreadIDW,ThreadIDA:DWORD;
      WSAData:TWSAData;
      SvrAddr:TSockAddr;
      RemoteIP,port:string;
      RetC:integer;
      
    begin
      RemoteIP:='127.0.0.1';
      port:='9995';
    //init Socket
      if (WSAStartup(MAKEWORD(2,2),WSAData)<>0) then
         showmessage('Init Failed');//初始化失败
    //1.create a Server socket
      ServerScok:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    //valid check
      if(ServerScok=INVALID_SOCKET) then
        showmessage('Error on create socket');
      ZeroMemory(@SvrAddr,sizeof(SvrAddr));
      SvrAddr.sin_family := AF_INET;
      SvrAddr.sin_port := htons(strtoint(port));
      SvrAddr.sin_addr.S_addr:=INADDR_ANY;
      RetC:=bind(ServerScok,SvrAddr,sizeof(SvrAddr));
      if RetC=SOCKET_ERROR then
      begin
        showmessage('Error on Bind socket');
        application.Terminate;
      end;
      RetC:=Listen(ServerScok, 5);
      if RetC=SOCKET_ERROR then
        showmessage('Error on Listen socket');
    //create pipe
      inipipe;
      SetupSecurity;
      CreateIOPiping;
      
      GetStartupInfo(si);      //set startupinfo for the spawned process
      si.wShowWindow:=SW_HIDE;
      si.dwFlags := STARTF_USESTDHANDLES OR STARTF_USESHOWWINDOW;
      si.hStdOutput := hWritePipe;
      si.hStdError := hWritePipe;     //set the new handles for the child process
      si.hStdInput := hReadPipe;
    //create proc
      If Not CreateChildProcess( 'd:\winnt\system32\cmd.exe', '' ) Then
        Showmessage('Failed to spawn a child');
    //create Thread
      hThreadR:=CreateThread(nil, 0,@Readpipe,nil, 0, ThreadIDR);
      if hThreadR=0 then
        showmessage('Failed to CreateThread ReadPipe');
      hThreadW:=CreateThread(nil, 0,@WritePipe,nil, 0, ThreadIDW);
      if hThreadW=0 then
        showmessage('Failed to CreateThread WritePipe');
      hThreadA:=CreateThread(nil, 0,@AcceptConnect,nil, 0, ThreadIDA);
      if hThreadA=0 then
        showmessage('Failed to CreateThread WritePipe');
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      // Make sure all handles are closed
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
      CloseHandle(hWritePipe);            //clean stuff up
      CloseHandle(hReadPipe);
      CloseHandle(hReadFile);
      CloseHandle(hWriteFile);
    //  closesocket(ServerScok);
    //  closesocket(ClientSock);
    //release winsock
      WSACleanUP();
    end;end.