web-dev-qa-db-ja.com

Inno SetupでExecされたプログラムの出力を取得するにはどうすればよいですか?

Exec'ed実行可能ファイルの出力を取得することは可能ですか?

ユーザーに情報クエリページを表示したいのですが、入力ボックスにMACアドレスのデフォルト値を表示します。これを達成する他の方法はありますか?

32
versioner

はい、ファイルへの標準出力のリダイレクトを使用します。

[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アドレスから選択できることに注意してください。

36
mghie

私は同じことをしなければならず(コマンドライン呼び出しを実行して結果を取得する)、より一般的な解決策を考え出しました。

また、/Scmd.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;
17
Tobias81