使用TProcess运行时控制台应用程序永远不会返回

时间:2013-01-04 14:20:33

标签: lazarus windows-console fpc

我正在使用Windows Server 2008,我想获得DNS服务器。所以我认为最快的方法应该是执行ipconfig然后使用TProcess解析它的输出。

我想出了这段代码:

  var
  proces : TProcess;
  begin
  ...
  proces := TProcess.Create(nil);
  proces.Executable := 'ipconfig';
  proces.Options := proces.Options + [poWaitOnExit,poUsePipes];
  try
  proces.Execute;
  except
        proces.Free;
  end;
  SetLength(rez,proces.Output.NumBytesAvailable);
  proces.Output.Read(rez[1],proces.Output.NumBytesAvailable);
  ShowMessage(rez);

代码可以工作,但是在我手动关闭控制台窗口之后。我尝试了poNoConsole但结果仍然相同,进程ipconfig在taskmanager中保持活动状态。

为什么控制台应用程序ipconfig没有终止?如果我运行它,它会在吐出标准信息后退出。

是我的配置吗?这是一个错误吗?救命!谢谢:))

1 个答案:

答案 0 :(得分:1)

由于ipconfig可以生成大量输出,因此请不要尝试一次性读取它,使用wiki中的Reading large output方法。

FPC的下一次迭代(2.6.2)将有一堆runcommand程序,用于处理一系列常见情况并将输出返回到单个字符串中。

注意API解决方案也是可能的:

{$mode delphi}

uses  JwaIpExport, JwaIpRtrMib, JwaIpTypes,jwawinerror,classes,jwaiphlpapi;

procedure GetDNSServers(AList: TStringList);
var
  pFI: PFixed_Info;
  pIPAddr: PIPAddrString;
  OutLen: Cardinal;
begin
  AList.Clear;
  OutLen := SizeOf(TFixedInfo);
  GetMem(pFI, SizeOf(TFixedInfo));
  try
    if GetNetworkParams(pFI, OutLen) = ERROR_BUFFER_OVERFLOW then
    begin
      ReallocMem(pFI, OutLen);
      if GetNetworkParams(pFI, OutLen) <> NO_ERROR then Exit;
    end;
    // If there is no network available there may be no DNS servers defined
    if pFI^.DnsServerList.IpAddress.s[0] = #0 then Exit;
    // Add first server
    AList.Add(pFI^.DnsServerList.IpAddress.s);
    // Add rest of servers
    pIPAddr := pFI^.DnsServerList.Next;
    while Assigned(pIPAddr) do
    begin
      AList.Add(pIPAddr^.IpAddress.s);
      pIPAddr := pIPAddr^.Next;
    end;
  finally
    FreeMem(pFI);
  end;
end;

var v : TStringList; 
    s : string;
begin
 v:=tstringlist.create;
 getdnsservers(v);
 for s in v do writeln(s);   // this probably requires 2.6+
 v.free;
end.