执行命令行, 并获取输出字符(比如OSQL)

时间:2023-03-08 23:41:09
执行命令行, 并获取输出字符(比如OSQL)

直接贴代码了, 没什么好说的, 很简单, 也不需要注释

function DoCMD(ACommand: AnsiString; var ACmdResult: string): Boolean;
var
nStrs: TStringBuilder; {旧版本可以用TStringlist替代}
nHReadPipe, nHWritePipe: THandle;
nSI: STARTUPINFOA;
nLSA: SECURITY_ATTRIBUTES;
nPI: PROCESS_INFORMATION;
nBufferSize, nRBufferSize, nEC: DWORD;
nPH: array[..] of AnsiChar;
begin
Result := False; with nLSA do
begin
nLength := SizeOf(SECURITY_ATTRIBUTES);
lpSecurityDescriptor := nil;
bInheritHandle := True;
end; if not CreatePipe(nHReadPipe, nHWritePipe, @nLSA, ) then
raise Exception.Create('管道创建失败 ' + SysErrorMessage(GetLastError)); try
GetStartupInfoA(nSI);
with nSI do
begin
dwFlags := (STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
wShowWindow := SW_HIDE;
hStdOutput := nHWritePipe;
end; nStrs := TStringBuilder.Create;
try
if not CreateProcessA(nil, PAnsiChar(ACommand), nil, nil,
True, , nil, nil, nSI, nPI) then
raise Exception.Create('进程创建失败 ' + SysErrorMessage(GetLastError));
try
nRBufferSize := ;
repeat
GetExitCodeProcess(nPI.hProcess, nEC);
PeekNamedPipe(nHReadPipe, @nPH, Length(nPH) - , @nBufferSize, nil, nil);
if nBufferSize <> then
begin
ReadFile(nHReadPipe, nPH, nBufferSize, nRBufferSize, nil);
nPH[nRBufferSize] := #;
nRBufferSize := ;
nStrs.Append(nPH);
end;
until nEC <> STILL_ACTIVE;
nPH[nRBufferSize] := #;
nStrs.Append(nPH);
ACmdResult := nStrs.ToString;
Result := True;
finally
CloseHandle(nPI.hThread);
CloseHandle(nPI.hProcess);
end;
finally
nStrs.Free;
end;
finally
CloseHandle(nHReadPipe);
CloseHandle(nHWritePipe);
end;
end;