比如我想使用createprocess调用“netstat -an”,该如何调用啊?我将第二个参数设为'cmd/c netstat -an'时总不行。

解决方案 »

  1.   

    我其实是想控制一个命令行程序并接收它的输出,代码如下:
    procedure RunDos(const DosApp: string; var OutStr:Tstrings);
    //DosApp是要执行的DOS指令或控制台程序,输出结果显示在OutStr中.
    const
           {设置ReadBuffer的大小}
           ReadBuffer = 2400;
    var
           Security: TSecurityAttributes;
           ReadPipe, WritePipe: THandle;
           start: TStartUpInfo;
           ProcessInfo: TProcessInformation;
           Buffer: PChar;
           BytesRead: DWord;
           Buf: string;
           fName : pchar;
    begin
           with Security do
           begin
             nlength := SizeOf(TSecurityAttributes);
             binherithandle := true;
             lpsecuritydescriptor := nil;
           end;
           {创建一个命名管道用来捕获console程序的输出}
           if Createpipe(ReadPipe, WritePipe, @Security, 0) then
           begin
             Buffer := AllocMem(ReadBuffer + 1);
             FillChar(Start, Sizeof(Start), #0);
             {设置console程序的启动属性}
             with start do
             begin
               cb := SizeOf(start);
               start.lpReserved := nil;
               lpDesktop := nil;
               lpTitle := nil;
               dwX := 0;
               dwY := 0;
               dwXSize := 0;
               dwYSize := 0;
               dwXCountChars := 0;
               dwYCountChars := 0;
               dwFillAttribute := 0;
               cbReserved2 := 0;
               lpReserved2 := nil;
               hStdOutput := WritePipe; //将输出定向到我们建立的WritePipe上
               hStdInput := ReadPipe; //将输入定向到我们建立的ReadPipe上
               hStdError := WritePipe;//将错误输出定向到我们建立的WritePipe上
               dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
               wShowWindow := SW_HIDE;//设置窗口为hide
             end;         try
               StrPCopy(fName,Form1.Edit1.Text);
               {创建一个子进程,运行console程序}
               if CreateProcess(nil, PChar(DosApp), @Security, @Security, true,
                 NORMAL_PRIORITY_CLASS,
                 nil, nil, start, ProcessInfo) then
               begin
                {等待进程运行结束}
                 WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
                 {关闭输出...开始没有关掉它,结果如果没有输出的话,程序死掉了。}
                 CloseHandle(WritePipe);
                 Buf := '';
                 {读取console程序的输出}
                 repeat
                   BytesRead := 0;
                   ReadFile(ReadPipe, Buffer[0], ReadBuffer, BytesRead, nil);
                   Buffer[BytesRead] := #0;
                   OemToAnsi(Buffer, Buffer);
                   Buf := Buf + string(Buffer);
                 until (BytesRead < ReadBuffer);
                 //SendDebug(Buf);
                {按照换行符进行分割,并在OutStr中显示出来}
                 ShowMessage(Buf);
                 {
                 while pos(#10, Buf) > 0 do
                 begin
                   OutStr.Add(Copy(Buf, 1, pos(#10, Buf) - 1));
                   Delete(Buf, 1, pos(#10, Buf));
                 end;
                 }
               end;
             finally
               FreeMem(Buffer);
               CloseHandle(ProcessInfo.hProcess);
               CloseHandle(ProcessInfo.hThread);
               CloseHandle(ReadPipe);
             end;
           end;
    end;
    我是想测试netstat -an, 但是不行,输不出来,各位帮一下忙,急,多谢了
      

  2.   

    --我测试没有问题
    procedure TForm1.Button1Click(Sender: TObject);
      var str:TStrings;
      procedure RunDos(const DosApp: string; var OutStr:Tstrings);
      //DosApp是要执行的DOS指令或控制台程序,输出结果显示在OutStr中.
      const
            {设置ReadBuffer的大小}
            ReadBuffer = 2400;
      var
            Security: TSecurityAttributes;
            ReadPipe, WritePipe: THandle;
            start: TStartUpInfo;
            ProcessInfo: TProcessInformation;
            Buffer: PChar;
            BytesRead: DWord;
            Buf: string;
            fName : pchar;
      begin
            with Security do
            begin
              nlength := SizeOf(TSecurityAttributes);
              binherithandle := true;
              lpsecuritydescriptor := nil;
            end;
            {创建一个命名管道用来捕获console程序的输出}
            if Createpipe(ReadPipe, WritePipe, @Security, 0) then
            begin
              Buffer := AllocMem(ReadBuffer + 1);
              FillChar(Start, Sizeof(Start), #0);
              {设置console程序的启动属性}
              with start do
              begin
                cb := SizeOf(start);
                start.lpReserved := nil;
                lpDesktop := nil;
                lpTitle := nil;
                dwX := 0;
                dwY := 0;
                dwXSize := 0;
                dwYSize := 0;
                dwXCountChars := 0;
                dwYCountChars := 0;
                dwFillAttribute := 0;
                cbReserved2 := 0;
                lpReserved2 := nil;
                hStdOutput := WritePipe; //将输出定向到我们建立的WritePipe上
                hStdInput := ReadPipe; //将输入定向到我们建立的ReadPipe上
                hStdError := WritePipe;//将错误输出定向到我们建立的WritePipe上
                dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
                wShowWindow := SW_HIDE;//设置窗口为hide
              end;          try
                //StrPCopy(fName,Form1.Edit1.Text);
                {创建一个子进程,运行console程序}
                if CreateProcess(nil, PChar(DosApp), @Security, @Security, true,
                  NORMAL_PRIORITY_CLASS,
                  nil, nil, start, ProcessInfo) then
                begin
                  {等待进程运行结束}
                  WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
                  {关闭输出...开始没有关掉它,结果如果没有输出的话,程序死掉了。}
                  CloseHandle(WritePipe);
                  Buf := '';
                  {读取console程序的输出}
                  repeat
                    BytesRead := 0;
                    ReadFile(ReadPipe, Buffer[0], ReadBuffer, BytesRead, nil);
                    Buffer[BytesRead] := #0;
                    OemToAnsi(Buffer, Buffer);
                    Buf := Buf + string(Buffer);
                  until (BytesRead < ReadBuffer);
                  //SendDebug(Buf);
                  {按照换行符进行分割,并在OutStr中显示出来}
                  ShowMessage(Buf);
                  {
                  while pos(#10, Buf) > 0 do
                  begin
                    OutStr.Add(Copy(Buf, 1, pos(#10, Buf) - 1));
                    Delete(Buf, 1, pos(#10, Buf));
                  end;
                  }
                end;
              finally
                FreeMem(Buffer);
                CloseHandle(ProcessInfo.hProcess);
                CloseHandle(ProcessInfo.hThread);
                CloseHandle(ReadPipe);
              end;
            end;
      end;begin
      str:=TStrings.Create;
      RunDos('netstat -na',str);
      str.Free;
    end;
    --showmessage内容---------------------------
    Project1
    ---------------------------Active Connections  Proto  Local Address          Foreign Address        State
      TCP    0.0.0.0:25             0.0.0.0:0              LISTENING
      TCP    0.0.0.0:80             0.0.0.0:0              LISTENING
      TCP    0.0.0.0:135            0.0.0.0:0              LISTENING
      TCP    0.0.0.0:443            0.0.0.0:0              LISTENING
      TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
      TCP    0.0.0.0:1025           0.0.0.0:0              LISTENING
      TCP    0.0.0.0:1026           0.0.0.0:0              LISTENING
      TCP    0.0.0.0:2030           0.0.0.0:0              LISTENING
      TCP    0.0.0.0:6059           0.0.0.0:0              LISTENING
      TCP    127.0.0.1:1031         0.0.0.0:0              LISTENING
      TCP    192.168.1.168:139      0.0.0.0:0              LISTENING
      TCP    192.168.1.168:1289     211.100.26.98:80       ESTABLISHED
      UDP    0.0.0.0:445            *:*                    
      UDP    0.0.0.0:500            *:*                    
      UDP    0.0.0.0:1035           *:*                    
      UDP    0.0.0.0:1036           *:*                    
      UDP    0.0.0.0:1434           *:*                    
      UDP    0.0.0.0:3456           *:*                    
      UDP    0.0.0.0:4500           *:*                    
      UDP    127.0.0.1:123          *:*                    
      UDP    127.0.0.1:1034         *:*                    
      UDP    127.0.0.1:1131         *:*                    
      UDP    127.0.0.1:1900         *:*                    
      UDP    192.168.1.168:123      *:*                    
      UDP    192.168.1.168:137      *:*                    
      UDP    192.168.1.168:138      *:*                    
      UDP    192.168.1.168:1900     *:*                    ---------------------------
    OK   
    ---------------------------
      

  3.   

    谢谢楼上的,我在winxp下可以测试成功,但是,在win2003下就死掉了,不知道怎么回事,调试执行时,发现在
    WaitForSingleObject那个函数那儿就执行不下去了,一直在等待。