function TFDFUtil.RunCmdAsAnsiStringAndReadInMemStream(cmd: AnsiString; memStream: TMemoryStream): DWORD ;
const
ReadBufferCONST = 2048;
var
security : TSecurityAttributes;
readPipe, WritePipe : THandle;
start : TStartUpInfo;
processInfo : TProcessInformation;
bytesRead, bytesReadTotal : DWord;
apprunning, exitCode : DWord;
i: Integer;
begin
BytesRead := 0;
bytesReadTotal := 0;
Security.nlength := SizeOf(TSecurityAttributes);
Security.binherithandle := true;
Security.lpsecuritydescriptor := nil;
// Create Pipes
if Createpipe (ReadPipe, WritePipe, @Security, 0) then
begin
FillChar(Start,Sizeof(Start),#0);
start.cb := SizeOf(start);
start.hStdOutput := WritePipe;
start.hStdInput := ReadPipe;
start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.wShowWindow := SW_HIDE;
// Create process
if CreateProcess(nil, PChar(cmd), @Security, @Security, true, NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo) then
begin
repeat
// make sure we have room
MemStream.SetSize(bytesReadTotal + ReadBufferCONST);
ReadFile(ReadPipe, (MemStream.Memory + bytesReadTotal)^, ReadBufferCONST, BytesRead, nil);
bytesReadTotal := bytesReadTotal + BytesRead;
if (BytesRead < ReadBufferCONST) then
begin
logging.log('RunCmdAsAnsiStringAndReadInMemStream', 'Readed in total: ' + IntToStr(bytesReadTotal + BytesRead));
break;
end;
Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 1);
until (Apprunning <> WAIT_TIMEOUT);
if (apprunning = WAIT_FAILED) then
begin
exitCode := GetLastError();
logging.log('oFoilUtil | RunCmdAsAnsiString', 'System Error Codes: ' + IntToStr(exitCode));
end;
end;
// Check return value
GetExitCodeProcess(ProcessInfo.hProcess, &exitCode);
if (exitCode <> 0) then
begin
ShowMessage('Error: ' + cmd + ' failed with ' + IntToStr(exitCode));
logging.log('oFoilUtil | RunCmdAsAnsiString', 'Error: ' + cmd + ' failed with ' + IntToStr(exitCode));
end;
// Free everything
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
CloseHandle(WritePipe);
result := exitCode;
end;
end;