Reputation: 9
I wrote a tiny little console app that archives files using their dates. Files with same date goes to the same archive. My app calls the rar.exe archiver upon every bunch of files using the method described in this thread : How can I run a console application within my Delphi console application?
The probelm is that if I redirect the output with standard DOS pipe redirection characters '>' and '>>' into a log file, then my program's writelns and rar.exe's own text output gets mixed with each other, does not follow the order dictated by code lines.
If I miss the pipe redirection, the problem does not exist.
Therefore it looks like something related to disk writing strategies used by the OS Windows 10 Pro.
for i:=0 to DateList.Count-1 do begin
Writeln(' ');
Writeln(DateTimeToStr(Now()) + ' - ' + 'Creating archive file ' + IntToStr(i+1) + ' of ' + IntToStr(DateList.Count) + ' = ' + DateList[i] + '.rar');
Writeln(' ');
//Sleep(1000); // does not help
// Writelns and RAR output gets scrambled
s:=DateList[i];
s1:='';//DateList[i] + EOL;
for j:=0 to FileList.Count-1 do
if pos(DateList[i],FileList[j])>0 then s1:=s1 + GetValuePart(FileList[j]) + EOL;
try
//s2:=ExtractFilePath(ParamStr(0)) + {'\' +} s + '.lst';
s2:=ExtractFilePath(ParamStr(0)) + {'\' + s +} 'list.lst';
ListFile:=TFileStream.Create(s2,fmCreate or fmShareDenyWrite);
if ListFile.Write(PChar(s1)^,Length(s1))<>Length(s1) then ; // report list file write error
finally
ListFile.Free;
end;
s1:=IniFile.ReadString('Settings','RARPath',ExtractFilePath(ParamStr(0))) + 'rar.exe';
s2:=IniFile.ReadString('Settings','ArchiveMode','a') + ' -ep "' +
IniFile.ReadString('Settings','OperatingDir','') +
IniFile.ReadString('Settings','ArchiveDir','') +
s + '.rar" @"' + s2 + '"';
s := s1 + ' ' + s2;
//s := s + ' >> logfile.log'; // gets interpreted as RAR parameter
UniqueString(s);
try
try
//writeln('begin');
FillChar(SI, sizeof(SI), 0);
FillChar(PI, sizeof(PI), 0);
SI.cb := sizeof(SI);
if not CreateProcess(nil, PChar(s), nil, nil, true, 0, nil, nil, SI, PI) then
Writeln('Cannot start RAR archiver ' + s);
//RaiseLastOSError;
WaitForSingleObject(PI.hProcess, INFINITE);
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
//writeln('end');
inc(SuccessFiles);
except
on E: Exception do Writeln(E.ClassName, ': ', E.Message);
end;
finally
//Readln;
end;
s2:='';
end;
Here the lines starting with date/time stamps are the program own outputs, other lines are RAR archiver outputs. You can see the two types of text getting mixed.
2019. 03. 25. 14:03:15 - Starting file archiving operation
2019. 03. 25. 14:03:15 - d:\Temp\testing\phx\
2019. 03. 25. 14:03:15 - 279 files found total
2019. 03. 25. 14:03:15 - 103 different dates found
2019. 03. 25. 14:03:15 - Creating archive file 1 of 103 = 2017. 04. 12..rar
RAR 4.11 Copyright (c) 1993-2012 Alexander Roshal 17 Feb 2012
Shareware version Type RAR -? for help
Evaluation copy. Please register.
Updating archive d:\Temp\testing\phx\archived\2017. 04. 12..rar
Updating d:\Temp\testing\phx\E00186000_PP20_0_KARAT.CSV 23% OK
Updating d:\Temp\testing\phx\E00186000_PP21_0_KARAT.CSV 100% OK
Deleting d:\Temp\testing\phx\E00186000_PP21_0_KARAT.CSV deleted
Deleting d:\Temp\testing\phx\E00186000_PP20_0_KARAT.CSV deleted
Done
2019. 03. 25. 14:03:16 - Crea
RAR 4.11 Copyright (c) 1993-2012 Alexander Roshal 17 Feb 2012
Shareware version Type RAR -? for help
Evaluation copy. Please register.
Updating archive d:\Temp\testing\phx\archived\2017. 05. 15..rar
Updating d:\Temp\testing\phx\E00398000_PP64_0_KARAT.CSV 31% OK
Updating d:\Temp\testing\phx\E00398000_PP65_0_KARAT.CSV 47% OK
Updating d:\Temp\testing\phx\E00398000_PP69_0_KARAT.CSV 73% OK
Updating d:\Temp\testing\phx\E00398000_PP73_0_KARAT.CSV 89% OK
Updating d:\Temp\testing\phx\E00398000_PP83_0_KARAT.CSV 100% OK
Deleting d:\Temp\testing\phx\E00398000_PP83_0_KARAT.CSV deleted
Deleting d:\Temp\testing\phx\E00398000_PP73_0_KARAT.CSV deleted
Deleting d:\Temp\testing\phx\E00398000_PP69_0_KARAT.CSV deleted
Deleting d:\Temp\testing\phx\E00398000_PP65_0_KARAT.CSV deleted
Deleting d:\Temp\testing\phx\E00398000_PP64_0_KARAT.CSV deleted
Done
ting archive file 2 of 103 = 2017. 05. 15..rar
RAR 4.11 Copyright (c) 1993-2012 Alexander Roshal 17 Feb 2012
Shareware version Type RAR -? for help
Evaluation copy. Please register.
Updating archive d:\Temp\testing\phx\archived\2017. 05. 16..rar
Updating d:\Temp\testing\phx\E00398000_PP111_0_KARAT.CSV 54% OK
Updating d:\Temp\testing\phx\E00398000_PP114_0_KARAT.CSV 100% OK
Deleting d:\Temp\testing\phx\E00398000_PP114_0_KARAT.CSV deleted
Deleting d:\Temp\testing\phx\E00398000_PP111_0_KARAT.CSV deleted
Done
2019. 03. 25. 14:03:17 - Creating archive file 3 of 103 = 2017. 05. 16..rar
2019. 03. 25. 14:03:18 - Creating archive file 4 of 103 = 201
RAR 4.11 Copyright (c) 1993-2012 Alexander Roshal 17 Feb 2012
Shareware version Type RAR -? for help
Evaluation copy. Please register.
Updating archive d:\Temp\testing\phx\archived\2017. 05. 18..rar
Updating d:\Temp\testing\phx\E01125000_PP266_0_KARAT.CSV 59% OK
Updating d:\Temp\testing\phx\E01125000_PP275_0_KARAT.CSV 100% OK
Deleting d:\Temp\testing\phx\E01125000_PP275_0_KARAT.CSV deleted
Deleting d:\Temp\testing\phx\E01125000_PP266_0_KARAT.CSV deleted
Done
7. 05. 18..rar
Thans for any help in advance.
Peter :-))
Upvotes: 0
Views: 208
Reputation: 9
The following code solved the problem.
unit uDOSOutput;
interface
uses Windows;
function ExecuteCommand(CommandLine:string):string;
var
mCommand: string;
mOutputs: string;
implementation
function ExecuteCommand(CommandLine:string):string;
var
PROC: TProcessInformation;
Ret: LongBool;
START: TStartupInfo;
SA: TSecurityAttributes;
hReadPipe: THandle;
hWritePipe: THandle;
dBytesRead: DWORD;
sBuff: array[0..255] of Char;
begin
if Length(CommandLine) > 0 then
mCommand := CommandLine;
if Length(mCommand) = 0 then
begin
MessageBox(0, PChar('Command Line empty.'), PChar('Error'), MB_ICONEXCLAMATION);
Exit;
end;
SA.nLength := SizeOf(TSecurityAttributes);
SA.bInheritHandle := TRUE;
SA.lpSecurityDescriptor := nil;
Ret := CreatePipe(hReadPipe, hWritePipe, @SA, 0);
if not Ret then
begin
MessageBox(0, PChar('CreatePipe() failed.'), PChar('Error'), MB_ICONEXCLAMATION);
Exit;
end;
FillChar(START ,Sizeof(TStartupInfo), #0);
START.cb := SizeOf(TStartupInfo);
START.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
START.hStdOutput := hWritePipe;
START.hStdError := hWritePipe;
Ret := CreateProcess(nil, PChar(mCommand), @SA, @SA, TRUE, NORMAL_PRIORITY_CLASS, nil, nil, START, PROC);
if Ret <> TRUE then
begin
MessageBox(0, PChar('File or command not found.'), PChar('Error'), MB_ICONEXCLAMATION);
Exit;
end;
Ret := CloseHandle(hWritePipe);
mOutputs := '';
repeat
Ret := ReadFile(hReadPipe, sBuff, 255, dBytesRead, nil);
mOutputs := mOutputs + Copy(sBuff, 1, dBytesRead);
until Ret = FALSE;
Ret := CloseHandle(PROC.hProcess);
Ret := CloseHandle(PROC.hThread);
Ret := CloseHandle(hReadPipe);
ExecuteCommand := mOutputs
end;
end.
Origin : http://www.delphibasics.info/home/delphibasicssnippets/capturetheoutputofadosapplication
Upvotes: 1
Reputation: 1483
From your question it is not clear to me whether you actually want RAR.EXE's output included in your log file or not. If you do not need it in your log, then I would suggest calling RAR.EXE like this:
C:\windows\system32\cmd.exe /c "[path]\rar.exe" "[rar.exe parameters]"
This should open RAR.EXE in a second, independent console window.
Upvotes: 0