J'essaie plusieurs échantillons sur internet et aucun d'entre eux ne fonctionne - les scripts ne sont pas exécutés - (peut-être parce qu'ils sont pré-Delphi 2009 unicode?).Comment dans Delphi 2009 rediriger la console (stin, sterr)?
Je dois exécuter des scripts python et passer des arguments à eux, comme:
python "..\Plugins\RunPlugin.py" -a login -u Test -p test
et capturer la sortie à une chaîne & les erreurs à l'autre.
C'est ce que j'ai maintenant:
procedure RunDosInMemo(DosApp:String; var OutData: String);
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of Char;
BytesRead: Cardinal;
WorkDir: string;
Handle: Boolean;
begin
OutData := '';
with SA do begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
try
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES or CREATE_UNICODE_ENVIRONMENT;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
WorkDir := 'C:\';
Handle := CreateProcess(nil, PChar(DosApp),
nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);
CloseHandle(StdOutPipeWrite);
if Handle then
begin
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
OutData := OutData + String(Buffer);
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(PI.hProcess, INFINITE);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
end else begin
raise Exception.Create('Failed to load python plugin');
end;
finally
CloseHandle(StdOutPipeRead);
end;
end;
Si le script ne s'est pas exécuté auparavant, ces modifications ne permettent pas l'exécution du script. La boucle "for" s'exécute une fois de trop; corrige cela, et l'affectation de zéro dans Buffer [BytesRead] n'a plus aucun effet. Évitez le type-cast en déclarant Buffer comme un tableau d'AnsiChar dès le début. Quel est le but de votre appel WaitForSingleObject? Vous ignorez la valeur de retour. –
L'appel waitforsingleobject est un espace réservé pour "graver du temps". Un sleep aurait aussi fonctionné, mais waitforsingleobject avec un timeout dit simplement d'attendre que l'application ne fonctionne plus. J'essayais juste de ne pas écraser le CPU dans la boucle. – skamradt
Ok, je copie ce code d'ailleurs, je n'ai pas de compétences en développement d'API donc je comprends à peine ce qui se passait. Merci pour votre contribution! – mamcx