Help Me..........

解决方案 »

  1.   

    我也在想这个问题,我要的是象ping或者mpq2000(一个关于暴雪公司文件解压的……)的结果;
    重定向+读文件;例: dir *.* >"c:\temp\result.txt",然后读文件;不过这显然是个很dirty的办法;
    另一个想法是建个文件,叫xx.dat;换汤不换药的用重定向写入,用text驱动的ODBC源读出,蒙蒙人;我在http://expert.csdn.net/Expert/TopicView1.asp?id=1190137帖子
      

  2.   

    找到于msdn;Knowledge Base Articles   HOWTO: Spawn Console Processes with Redirected Standard Handles
    Q190351……csdn不让贴那么多
    SUMMARY
    This article describes how to redirect the input and output of a child process that receives input from the standard input handle or sends output to the standard output handle. The Win32 API enables applications to spawn a child console process with redirected standard handles. This feature allows a parent process to send and receive the input and output of the child process. NOTE: Some console based applications do not use the standard handles for their input/output (IO) operations. The Win32 API does not support redirection of these processes. MORE INFORMATION
    The CreateProcess() API through the STARTUPINFO structure enables you to redirect the standard handles of a child console based process. If the dwFlags member is set to STARTF_USESTDHANDLES, then the following STARTUPINFO members specify the standard handles of the child console based process: 
       HANDLE hStdInput - Standard input handle of the child process.
       HANDLE hStdOutput - Standard output handle of the child process.
       HANDLE hStdError - Standard error handle of the child process. 
    You can set these handles to either a pipe handle, file handle, or any handle that can do synchronous reads and writes through the ReadFile() and WriteFile() API. The handles must be inheritable and the CreateProcess() API must specify that inheritable handles are to be inherited by the child process by specifying TRUE in the bInheritHandles parameter. If the parent process only wishes to redirect one or two standard handles, specifying GetStdHandle() for the specific handles causes the child to create the standard handle as it normally would without redirection. For example, if the parent process only needs to redirect the standard output and error of the child process, then the hStdInput member of the STARTUPINFO structure is filled as follows:    hStdInput = GetStdHandle(STD_INPUT_HANDLE); 
    NOTE: Child processes that use such C run-time functions as printf() and fprintf() can behave poorly when redirected. The C run-time functions maintain separate IO buffers. When redirected, these buffers might not be flushed immediately after each IO call. As a result, the output to the redirection pipe of a printf() call or the input from a getch() call is not flushed immediately and delays, sometimes-infinite delays occur. This problem is avoided if the child process flushes the IO buffers after each call to a C run-time IO function. Only the child process can flush its C run-time IO buffers. A process can flush its C run-time IO buffers by calling the fflush() function.NOTE: Windows 95 and Windows 98 require an extra step when you redirect the standard handles of certain child processes. For additional information, please see the following article in the Microsoft Knowledge Base: 
    Q150956 INFO: Redirection Issues on Windows 95 MS-DOS Applications 
    The following sample redirects the standard input, output, and error of the child process specified in the CreateProcess call. This sample redirects the provided console process (Child.c). 
    Sample Code……
      

  3.   

    我写了一个把Cmd.exe输出标准的Tmemo控间上,代码如下:
    unit U_pipe;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TPipeForm = class(TForm)
        Editor: TMemo;
        procedure EditorKeyPress(Sender: TObject; var Key: Char);
        procedure FormDestroy(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure EditorKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
        procedure EditorMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
      private
        { Private declarations }
        CreateOk: Boolean;
    WPos: TPoint;
        hReadPipe, hWritePipe, hWriteFile, hReadFile: THandle;
        processinfo: PROCESS_INFORMATION;
        procedure SendCmdToShell(Const CmdStr: String);
        function GetCmdStr: string;
      public
        { Public declarations }
      end;var
      PipeForm: TPipeForm;implementation{$R *.dfm}procedure TPipeForm.EditorKeyPress(Sender: TObject; var Key: Char);
    var
      ECharPos: TPoint;
    begin
    if Key = Chr(VK_RETURN) then
      begin
    SendCmdToShell(GetCmdStr);
      end else if Key = Chr(VK_BACK) then
      begin
       ECharPos := Editor.CaretPos;
       if ECharPos.X = WPos.X + 1 then
         Key := #0;
      end;
    end;procedure TPipeForm.SendCmdToShell(Const CmdStr: String);
    var
    ShellCmdStr: array[0..256] of char;
      RBuffer: array[0..25000] of char;
      nByteToWrite: DWORD;
      nByteWritten: DWORD;
      nByteReaden: DWORD;
    begin
    if CreateOK then
      begin
        StrPCopy(ShellCmdStr, CmdStr);
        nByteToWrite := StrLen(ShellCmdStr);
        ShellCmdStr[nByteToWrite] := #13;
        ShellCmdStr[nByteToWrite+1] := #10;
    ShellCmdStr[nByteToWrite+2] := #0;
        Inc(nByteToWrite, 2);
        WriteFile(hWriteFile, ShellCmdStr, nByteToWrite, nByteWritten, nil);
        Sleep(400);
        Editor.Lines.Clear;
        FillChar(RBuffer, Sizeof(RBuffer), #0);
        ReadFile(hReadFile, RBuffer, 25000, nByteReaden, nil);
        Editor.Lines.Add(StrPas(RBuffer));
        WPos.Y := Editor.Lines.Count-1;
        WPos.X := Length(Editor.Lines[WPos.Y])-1;
      end;
    end;procedure TPipeForm.FormDestroy(Sender: TObject);
    var
    shellexitcode: Cardinal;
    begin
    if GetExitCodeProcess(processinfo.hProcess, shellexitcode) then
      begin
       if shellexitcode = STILL_ACTIVE then
    TerminateProcess(processinfo.hProcess, 0);
      end;
      if hWriteFile <> 0 then
       CloseHandle(hWriteFile);
      if hReadFile <> 0 then
       CloseHandle(hReadFile);
    end;procedure TPipeForm.FormCreate(Sender: TObject);
    var
    Pipeattr: SECURITY_ATTRIBUTES;
      ShellStartInfo: STARTUPINFO;
      shellstr: array [0..256] of char;
      RBuffer: array[0..25000] of char;
      I: Integer;
      nByteReaden: DWORD;
    begin
    CreateOK := False;
      I := 0;
      Editor.ReadOnly := False;
      Wpos.X := 0;
      WPos.Y := 0;
      with Pipeattr do
      begin
    nLength := Sizeof(SECURITY_ATTRIBUTES);
    lpSecurityDescriptor := nil;
    bInheritHandle := true;
      end; if CreatePipe(hReadPipe, hWriteFile, @Pipeattr, 0) then
       Inc(i);
    if CreatePipe(hReadFile, hWritePipe, @pipeattr, 0) then
       Inc(i);  GetStartupInfo(ShellStartInfo);
      with ShellStartInfo do
      begin
        dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
        hStdInput := hReadPipe;
        hStdError := hWritePipe;
        hStdOutput := hWritePipe;
        wShowWindow := SW_HIDE;
      end;
    GetSystemDirectory(@Shellstr, MAX_PATH+1);
      StrCat(@ShellStr, Pchar('\\cmd.exe'));
      if CreateProcess(Shellstr, nil, nil, nil, True, 0,
    nil, nil, ShellStartInfo, processinfo) then
    begin
        Inc(i);
      end else begin
       MessageBox(Handle, Pchar('调用Shell错误!'), Pchar('错误'), (MB_OK or MB_ICONERROR));
    end;
      if i = 3 then
      begin
       CreateOK := True;
        Editor.Lines.Clear;
        sleep(250);
    ReadFile(hReadFile, RBuffer, 25000, nByteReaden, nil);
       Editor.Lines.Add(StrPas(RBuffer));
    WPos.Y := Editor.Lines.Count-1;
        WPos.X := Length(Editor.Lines[WPos.Y])-1;
      end;
    end;procedure TPipeForm.EditorKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    var
      ECharPos: TPoint;
    begin
      ECharPos := Editor.CaretPos;
      if ECharPos.Y > WPos.Y then
       Editor.ReadOnly := False
      else if (ECharPos.Y = WPos.Y) and (ECharPos.X > WPos.X) then
      begin
       Editor.ReadOnly := False;
      end else
       Editor.ReadOnly := True;
    end;function TPipeForm.GetCmdStr: string;
    var
    LastLine: Integer;
    begin
    LastLine := Editor.Lines.Count - 1;
      if LastLine > WPos.Y then
      begin
    result := Editor.Lines[LastLine];
      end else if LastLine = WPos.Y then
      begin
       result := Editor.Lines[LastLine];
        result := Copy(result, WPos.X+2, Length(result));
      end else
      begin
       result := ' ';
      end;
    end;procedure TPipeForm.EditorMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      ECharPos: TPoint;
    begin
      ECharPos := Editor.CaretPos;
      if ECharPos.Y > WPos.Y then
       Editor.ReadOnly := False
      else if (ECharPos.Y = WPos.Y) and (ECharPos.X > WPos.X) then
       Editor.ReadOnly := False
      else
       Editor.ReadOnly := True;
    end;end.大家一起交流交流
      

  4.   

    感谢大家关心这个问题.
    我也在网上搜索好一阵子;只找到一个VB的例子,
    用vc++6.0做出来,的不到结果;
    平台是windows2000;
    在98平台上,程序挂起.
    请问 (昨夜星辰)是在windows2000系统上实现的吗?
    欢迎继续关注......
      

  5.   

    看我的
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        OpenDialog1: TOpenDialog;
        Button2: TButton;
        Memo1: TMemo;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }    function WinExecAndWait32(FileName:String;Visibility:Integer;var mOutputs:string):Cardinal;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    function TForm1.WinExecAndWait32(FileName:String;Visibility:Integer;var mOutputs:string):Cardinal;
    var
      sa:TSecurityAttributes;
      hReadPipe,hWritePipe:THandle;
      ret:BOOL;
      strBuff:array[0..255] of char;
      lngBytesread:DWORD;
      
      WorkDir:String;
      StartupInfo:TStartupInfo;
      ProcessInfo:TProcessInformation;
    begin
      FillChar(sa,Sizeof(sa),#0);
      sa.nLength := Sizeof(sa);
      sa.bInheritHandle := True;
      sa.lpSecurityDescriptor := nil;
      ret := CreatePipe(hReadPipe, hWritePipe, @sa, 0);  WorkDir:=ExtractFileDir(Application.ExeName);
      FillChar(StartupInfo,Sizeof(StartupInfo),#0);
      StartupInfo.cb:=Sizeof(StartupInfo);
      StartupInfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      StartupInfo.wShowWindow:=Visibility;  StartupInfo.hStdOutput:=hWritePipe;
      StartupInfo.hStdError:=hWritePipe;  if not CreateProcess(nil,
        PChar(FileName),               { pointer to command line string }
        @sa,                           { pointer to process security attributes }
        @sa,                           { pointer to thread security attributes }
        True,                          { handle inheritance flag }
    //    CREATE_NEW_CONSOLE or          { creation flags }
        NORMAL_PRIORITY_CLASS,
        nil,                           { pointer to new environment block }
        PChar(WorkDir),                { pointer to current directory name, PChar}
        StartupInfo,                   { pointer to STARTUPINFO }
        ProcessInfo)                   { pointer to PROCESS_INF }
        then Result := INFINITE {-1} else
      begin
    //    Form1.Hide;
    //    FileOpen(FileName,fmShareExclusive);
    //    SetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW);
        ret:=CloseHandle(hWritePipe);
        mOutputs:='';
        while ret do
        begin
          FillChar(strBuff,Sizeof(strBuff),#0);
          ret := ReadFile(hReadPipe, strBuff, 256, lngBytesread, nil);
          mOutputs := mOutputs + strBuff;
        end;    Application.ProcessMessages;
        WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
        GetExitCodeProcess(ProcessInfo.hProcess, Result);
        CloseHandle(ProcessInfo.hProcess);  { to prevent memory leaks }
        CloseHandle(ProcessInfo.hThread);
    //    Form1.Close;                        { exit application }
        ret := CloseHandle(hReadPipe);
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      Val:Cardinal;
      mOutputs:string;
      i:integer;
    begin
      Val:=WinExecAndWait32(Edit1.Text,SW_SHOWNORMAL,mOutputs);
      Memo1.Lines.Add('******Result******'+#13#10+IntToStr(Val));
      i:=1;
      while i<=length(mOutputs) do
      begin
        if mOutputs[i]=#10 then
        begin
          Insert(#13,mOutputs,i);
          i:=i+2;
        end
        else
          Inc(i);
      end;
      Memo1.Lines.Add('******Echo******'+#13#10+mOutputs);
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      OpenDialog1.InitialDir:=ExtractFilePath(ParamStr(0));
      if OpenDialog1.Execute then
        Edit1.Text:=Opendialog1.FileName;
    end;end.
      

  6.   

    我曾经用这个在delphi里来读取java程序在console输出的结果,效果应该还可以
      

  7.   

    我的程序是在win2000下使用delphi6编写的.
      

  8.   

    还有,好像在win98下不支持使用有名管道,只支持匿名管道。在我的程序中使用的是匿名管道,在win98下运行应该没有问题。