Консольное приложение никогда не возвращается при запуске с TProcess
Я использую 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 остается активным в диспетчере задач.
Почему консольное приложение ipconfig не завершается? Если я запускаю его, он завершает работу, выплевывая информацию о stdout.
Это моя конфигурация? Это ошибка? Помогите! Спасибо:)
1 ответ
Поскольку ipconfig может генерировать много выходных данных, не пытайтесь прочитать их за один раз, используйте метод чтения большого вывода из вики.
Следующая итерация FPC (2.6.2) будет иметь набор процедур runcommand, которые обрабатывают tprocess для ряда общих случаев и возвращают результат в одной строке.
Примечание 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.