【发布时间】:2010-11-11 07:52:15
【问题描述】:
是否可以获得Exec'ed 可执行文件的输出?
我想向用户显示一个信息查询页面,但在输入框中显示 MAC 地址的默认值。有没有其他方法可以做到这一点?
【问题讨论】:
标签: inno-setup
是否可以获得Exec'ed 可执行文件的输出?
我想向用户显示一个信息查询页面,但在输入框中显示 MAC 地址的默认值。有没有其他方法可以做到这一点?
【问题讨论】:
标签: inno-setup
是的,使用将标准输出重定向到文件:
[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 地址可供选择。
【讨论】:
ExpandConstant('{cmd}')。 (当然,最好还是使用适当的 API,而不是尝试捕获控制台命令的输出,因为后者可能会在没有通知的情况下发生变化,因为它是为人类设计的。)
var ExecStdout: AnsiString;
我不得不这样做(执行命令行调用并获得结果)并想出了一个更通用的解决方案。
如果在实际调用中使用 /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;
【讨论】:
tasklist 和taskkill 一起使用,以在安装和卸载期间检测并终止正在运行的应用程序。
ipconfig /? 不是错误,而是返回退出代码 1。如果您使用 ewNoWait 或 ewWaitUntilIdle,ResultCode 将始终为 259,这是 GetExitCodeProcess 函数的保留代码,意思是 STILL_ACTIVE。