如何在Inno Setup中获得Exec'ed程序的输出?

时间:2009-07-16 10:40:49

标签: inno-setup

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

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

2 个答案:

答案 0 :(得分:35)

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

[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地址。

答案 1 :(得分:15)

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

如果使用cmd.exe的{​​{1}}标记在实际调用中使用引用路径,它还可以修复奇怪的错误。

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