35

是否可以获得Exec'ed 可执行文件的输出?

我想向用户显示一个信息查询页面,但在输入框中显示 MAC 地址的默认值。有没有其他方法可以实现这一目标?

4

2 回答 2

40

是的,使用标准输出重定向到文件:

[Code]

function NextButtonClick(CurPage: Integer): Boolean;
var
  TmpFileName, ExecStdout: string;
  ResultCode: integer;
begin
  if CurPage = wpWelcome then begin
    TmpFileName := ExpandConstant('{tmp}') + '\ipconfig_results.txt';
    Exec('cmd.exe', '/C ipconfig /ALL > "' + TmpFileName + '"', '', SW_HIDE,
      ewWaitUntilTerminated, ResultCode);
    if LoadStringFromFile(TmpFileName, ExecStdout) then begin
      MsgBox(ExecStdout, mbInformation, MB_OK);
      { do something with contents of file... }
    end;
    DeleteFile(TmpFileName);
  end;
  Result := True;
end;

请注意,可能有多个网络适配器,因此有多个 MAC 地址可供选择。

于 2009-07-16T11:31:28.147 回答
23

我必须做同样的事情(执行命令行调用并获得结果)并提出了一个更通用的解决方案。

如果在实际调用中/S使用cmd.exe.

{ Exec with output stored in result. }
{ ResultString will only be altered if True is returned. }
function ExecWithResult(const Filename, Params, WorkingDir: String; const ShowCmd: Integer;
  const Wait: TExecWait; var ResultCode: Integer; var ResultString: String): Boolean;
var
  TempFilename: String;
  Command: String;
begin
  TempFilename := ExpandConstant('{tmp}\~execwithresult.txt');
  { Exec via cmd and redirect output to file. Must use special string-behavior to work. }
  Command :=
    Format('"%s" /S /C ""%s" %s > "%s""', [
      ExpandConstant('{cmd}'), Filename, Params, TempFilename]);
  Result := Exec(ExpandConstant('{cmd}'), Command, WorkingDir, ShowCmd, Wait, ResultCode);
  if not Result then
    Exit;
  LoadStringFromFile(TempFilename, ResultString);  { Cannot fail }
  DeleteFile(TempFilename);
  { Remove new-line at the end }
  if (Length(ResultString) >= 2) and (ResultString[Length(ResultString) - 1] = #13) and
     (ResultString[Length(ResultString)] = #10) then
    Delete(ResultString, Length(ResultString) - 1, 2);
end;

用法:

Success :=
  ExecWithResult('ipconfig', '/all', '', SW_HIDE, ewWaitUntilTerminated,
    ResultCode, ExecStdout) or
  (ResultCode <> 0);

结果也可以加载到TStringList对象中以获取所有行:

Lines := TStringList.Create;
Lines.Text := ExecStdout;
{ ... some code ... }
Lines.Free;
于 2015-12-03T15:40:26.330 回答