Peter Borosnyay
Peter Borosnyay

Reputation: 9

Console app output gets scrambled upon starting another console app using >> pipe redirection

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

Answers (2)

Peter Borosnyay
Peter Borosnyay

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

Olaf Hess
Olaf Hess

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

Related Questions