Je devais faire la même chose (exécuter des appels en ligne de commande et obtenir le résultat) et trouver une solution plus générale.
Il corrige également des bogues étranges si des chemins entre guillemets sont utilisés dans les appels réels en utilisant l'indicateur /S
pour 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;
Utilisation:
Success :=
ExecWithResult('ipconfig', '/all', '', SW_HIDE, ewWaitUntilTerminated,
ResultCode, ExecStdout) or
(ResultCode <> 0);
Le résultat peut également être chargé dans un objet TStringList
pour obtenir toutes les lignes:
Lines := TStringList.Create;
Lines.Text := ExecStdout;
{ ... some code ... }
Lines.Free;
Notez que plutôt que de coder en dur « cmd.exe "il est préférable d'utiliser' ExpandConstant ('{cmd}') '. (Bien sûr, il vaut mieux utiliser les API appropriées au lieu d'essayer de capturer la sortie des commandes de la console, car celles-ci peuvent changer sans préavis, puisqu'elles sont destinées aux humains.) – Miral
Pour clarifier: vous devez exécuter votre programme via la commande invite à obtenir la redirection. J'ai d'abord regardé cette réponse et a été confus pourquoi cela ne fonctionnait pas pour moi, la raison était parce que je ne savais pas que la redirection est une fonction de l'invite de commande plutôt que Windows, donc vous devez Exec sur cmd.exe/c –
pour l'installation unicode, doit utiliser: 'var ExecStdout: AnsiString;' – papo