gpt4 book ai didi

delphi - Delphi 2009 中如何重定向控制台(stdin、stderr)?

转载 作者:行者123 更新时间:2023-12-03 15:41:42 32 4
gpt4 key购买 nike

我在互联网上尝试了几个示例,但没有一个工作正常 - 脚本未执行 - (也许是因为适用于 Delphi 2009 之前的 unicode?)。

我需要运行一些 python 脚本并向它们传递参数,例如:

python "..\Plugins\RunPlugin.py" -a login -u Test -p test

并将输出捕获为字符串并将错误捕获为其他。

这就是我现在拥有的:

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;

最佳答案

Create_Unicode_Environment 是一个进程创建标志,用于 CreateFiledwCreationFlags 参数。它不是在 TStartupInfo 记录中使用的标志。如果您向 API 函数提供它们不理解的标志值,它们可能会失败;如果您向它们提供与您预期不同的标志值,它们可能会做出奇怪的事情。

您声明了 256 个 Char 的缓冲区;回想一下,Delphi 2009 中的 Char 是 2 字节 Unicode 类型。然后,您调用 ReadFile 并告诉它缓冲区的长度为 255 字节,而不是实际值 512。当文档说值是字节数时,请采用作为使用 SizeOf 函数的提示。

由于 ReadFile 读取字节,因此最好将缓冲区数组声明为字节大小元素的数组,例如 AnsiChar。这样,当您设置 Buffer[BytesRead] 时,您将不会包含实际读取的数据的两倍。

CreateProcess 的 Unicode 版本可能会修改其命令行参数。您必须确保传递给该参数的字符串的引用计数为 1。在调用 CreateProcess 之前调用 UniqueString(DosApp)

当 API 函数失败时,您当然会想知道原因。不要只是编造一个理由。使用提供的函数,例如 Win32CheckRaiseLastOSError。至少,调用 GetLastError,就像 MSDN 告诉您的那样。当更具体的异常类型可用时,不要抛出通用异常类型。

关于delphi - Delphi 2009 中如何重定向控制台(stdin、stderr)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/841047/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com