Question

I am using Windows Server 2008 and I want to get the DNS Server. So I tought that the fastest way should be executing ipconfig and then parsing it's output using TProcess.

I have came up with this code :

  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);

The code works but after I manually close the console window.I have tried poNoConsole but still the same result, the process ipconfig remains active in taskmanager.

Why isn't the console application ipconfig terminating ? If I run it it exits after spitting stdout information.

Is it my configuration? Is it a bug ? Help! thanks :)

Was it helpful?

Solution

Since ipconfig can generate a lot of output, don't try to read it in one go, use the Reading large output method from the wiki.

The next iteration of FPC (2.6.2) will have a bunch of runcommand procedures that instrument tprocess for a series of common cases and return the output in a single string.

Note API solutions are also possible:

{$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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top