Exec
'ed実行可能ファイルの出力を取得することはできますか?Inno SetupでExec'edプログラムの出力を取得する方法は?
ユーザーに情報クエリページを表示したいが、入力ボックスにMACアドレスのデフォルト値を表示したい。これを達成する他の方法はありますか?
Exec
'ed実行可能ファイルの出力を取得することはできますか?Inno SetupでExec'edプログラムの出力を取得する方法は?
ユーザーに情報クエリページを表示したいが、入力ボックスにMACアドレスのデフォルト値を表示したい。これを達成する他の方法はありますか?
ファイルに標準出力をはい、使用リダイレクション:
[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から選択するアドレスこと。
私は同じことをしなければなりませんでした(コマンドラインコールを実行して結果を得る)、もっと一般的な解決策が出ました。
cmd.exe
に/S
フラグを使用して、実際の呼び出しで引用符で囲まれたパスが使用されている場合、これは奇妙なバグも修正します。
{ 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
オブジェクトにロードすることができます:「CMD.EXEをハードコーディングするのではなく
Lines := TStringList.Create;
Lines.Text := ExecStdout;
{ ... some code ... }
Lines.Free;
このような詳細な例を提供してくれてありがとうございます。あなたは明らかにこれを得るために多くの問題を解決し、私に多くの時間を節約しました。私は 'tasklist'と' taskkill'でこれを使って、インストール中とアンインストール中に実行中のアプリケーションを検出して終了させます。 –
使用例の1つの軽微な問題:Execが成功し、ResultCode <> 0の場合、ResultCodeはWindowsエラーではなく呼び出されたプログラムの終了コードで埋められるため、SysErrorMessageは正しいメッセージを取得しません。また、ゼロ以外の終了コードが大丈夫かもしれません。コンテキストに応じてResultCodeを個別にテストすることをお勧めします。この混乱の詳細:https://github.com/jrsoftware/issrc/issues/190 –
はいこの例の例外メッセージは、Windowsのexit-codes => https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx – Tobias81
注意を"ExpandConstant( '{cmd}')'を使用する方が良い方法です。 (もちろん、コンソールコマンドの出力をキャプチャしようとするのではなく、適切なAPIを使用する方が良いでしょう。後者は予告なく変更される可能性があります。人間が意図しているためです) – Miral
説明のために:リダイレクトを求めるプロンプトが表示されます。私は最初にこの答えを見て、なぜこれが私のために働いていないのか混乱しました。なぜなら、私はリダイレクションがウィンドウではなくコマンドプロンプトの機能であることを認識しなかったからです。cmd.exe/c –
ユニコードのインストールでは、以下を使用する必要があります: 'ExecStdout:AnsiString;' – papo