gpt4 book ai didi

delphi - Delphi 2009 及更高版本中的捕获控制台

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

下面的代码适用于 Delphi XE,但 2400 缓冲区大小相当难看。

有人对清理这个例程有一些建议吗?并使 2400 限制消失(不定义 64000 缓冲区)。

谢谢


procedure TForm1.Button1Click(Sender: TObject);
begin
CaptureConsoleOutput('c:\windows\system32\ipconfig','',Memo1);
end;<p></p>

<p>procedure TForm1.CaptureConsoleOutput(const ACommand, AParameters: String; AMemo: TMemo);
const
CReadBuffer = 2400;
var
saSecurity: TSecurityAttributes;
hRead: THandle;
hWrite: THandle;
suiStartup: TStartupInfo;
piProcess: TProcessInformation;
pBuffer: array[0..CReadBuffer] of AnsiChar;
dRead: DWord;
dRunning: DWord;
begin
saSecurity.nLength := SizeOf(TSecurityAttributes);
saSecurity.bInheritHandle := True;
saSecurity.lpSecurityDescriptor := nil;</p>

<p>if CreatePipe(hRead, hWrite, @saSecurity, 0) then
begin
FillChar(suiStartup, SizeOf(TStartupInfo), #0);
suiStartup.cb := SizeOf(TStartupInfo);
suiStartup.hStdInput := hRead;
suiStartup.hStdOutput := hWrite;
suiStartup.hStdError := hWrite;
suiStartup.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
suiStartup.wShowWindow := SW_HIDE;</p>

<pre><code> if CreateProcess(nil, PChar(ACommand + ' ' + AParameters), @saSecurity,
@saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess)
then
begin
repeat
dRunning := WaitForSingleObject(piProcess.hProcess, 100);
Application.ProcessMessages();
repeat
dRead := 0;
ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);
pBuffer[dRead] := #0;

OemToAnsi(pBuffer, pBuffer);
AMemo.Lines.Add(String(pBuffer));
until (dRead < CReadBuffer);
until (dRunning <> WAIT_TIMEOUT);
CloseHandle(piProcess.hProcess);
CloseHandle(piProcess.hThread);
end;

CloseHandle(hRead);
CloseHandle(hWrite);
</code></pre>

<p>end;
end;</p>

<p></p>

最佳答案

我有一些代码可以做到这一点。我已经删除了各种不相关的部分,所以这可能无法按原样编译。但你应该明白:

  procedure ReadStdout(hstdout: THandle; out stdout: string);
var
Buffer: AnsiString;
FileSize: DWORD;
NumberOfBytesRead: DWORD;
begin
FileSize := SetFilePointer(hstdout, 0, nil, FILE_END);
if FileSize>0 then begin
SetLength(Buffer, FileSize);
SetFilePointer(hstdout, 0, nil, FILE_BEGIN);
ReadFile(hstdout, Buffer[1], FileSize, NumberOfBytesRead, nil);
//should really check that NumberOfBytesRead=FileSize
stdout := Buffer;
end else begin
stdout := '';
end;
end;

function CreateFileHandle(const FileName: string): THandle;
var
SecurityAttributes: TSecurityAttributes;
begin
ZeroMemory(@SecurityAttributes, SizeOf(SecurityAttributes));
SecurityAttributes.nLength := SizeOf(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor := nil;
SecurityAttributes.bInheritHandle := True;
Result := CreateFile(
PChar(FileName),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
@SecurityAttributes,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH,
0
);
end;

procedure Execute(const ExecutableFileName, DataFileName, TempFolder: string);
var
hstdin, hstdout: THandle;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
ExitCode: DWORD;
stdout: string;
begin
hstdin := CreateFileHandle(TempFolder+'stdin');
hstdout := CreateFileHandle(TempFolder+'stdout');
Try
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.hStdInput := hstdin;
StartupInfo.hStdError := hstdout;
if CreateProcess(
PChar(ExecutableFileName),
'',
nil,
nil,
True,
CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS,
nil,
PChar(TempFolder),
StartupInfo,
ProcessInfo
) then begin
Try
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess, ExitCode);
ReadStdout(hstdout, stdout);
Finally
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
End;
end else begin
//error;
end;
Finally
CloseHandle(hstdout);
CloseHandle(hstdin);
End;
end;

您有时会想要清理临时文件。

关于delphi - Delphi 2009 及更高版本中的捕获控制台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4905450/

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