Running DOS command and Capture The Results

Posted on 2003-03-25
Medium Priority
Last Modified: 2007-12-19
I need to run DOS commands (such as DIR, MKDIR, FORMAT, etc)
and capture the produced output. I have tried a few
options to execute external programs from Delphi (WinExec and FileRun)
but those functions do not capture the output (or do they?).
Does anyone know any other way to do this trick?

Question by:Fresh_
LVL 27

Expert Comment

ID: 8201247
use like

dir > result.txt

and open then the file result.txt

meikl ;-)

Expert Comment

ID: 8201922
I think you need to use the win32 api call CreateProcess here, substituting the output streams with your own..
you could also use ShellExecuteEx but I found CreateProcess
to be better, also for dos commands, you need to execute them with the shell (command.exe/cmd.exe)

links to code -

LVL 14

Accepted Solution

DragonSlayer earned 80 total points
ID: 8208921
 Example call   : CreateDOSProcessRedirected('C:\MyDOSApp.exe',
                                             'Please, record this message')
function CreateDOSProcessRedirected(const CommandLine, InputFile, OutputFile, ErrMsg :string):boolean;
  ROUTINE_ID = '[function: CreateDOSProcessRedirected ]';
  OldCursor     : TCursor;
  pCommandLine  : array[0..MAX_PATH] of char;
  pOutPutFile   : array[0..MAX_PATH] of char;
  StartupInfo   : TStartupInfo;
  ProcessInfo   : TProcessInformation;
  SecAtrrs      : TSecurityAttributes;
  hOutputFile   : THandle;

  Result := False;

  { check for InputFile existence }
  if not FileExists(InputFile)
    raise Exception.CreateFmt(ROUTINE_ID          + #10 +  #10 +
                              'Input file * %s *' + #10 +
                              'does not exist'    + #10 +  #10 +
                              ErrMsg, [InputFile]);

  { save the cursor }
  OldCursor     := Screen.Cursor;
  Screen.Cursor := crHourglass;

  { copy the parameter Pascal strings to null terminated strings }
  StrPCopy(pCommandLine, CommandLine);
  StrPCopy(pInputFile, InputFile);
  StrPCopy(pOutPutFile, OutputFile);


    { prepare SecAtrrs structure for the CreateFile calls
      This SecAttrs structure is needed in this case because
      we want the returned handle can be inherited by child process
      This is true when running under WinNT.
      As for Win95 the documentation is quite ambiguous }
    FillChar(SecAtrrs, SizeOf(SecAtrrs), #0);
    SecAtrrs.nLength              := SizeOf(SecAtrrs);
    SecAtrrs.lpSecurityDescriptor := nil;
    SecAtrrs.bInheritHandle       := True;

    { create the appropriate handle for the input file }
    hInputFile := CreateFile(
                             pInputFile,                            { pointer to name of the file }
                             GENERIC_READ or GENERIC_WRITE,         { access (read-write) mode }
                             FILE_SHARE_READ or FILE_SHARE_WRITE,   { share mode }
                             @SecAtrrs,                             { pointer to security attributes }
                             OPEN_ALWAYS,                           { how to create }
                             FILE_ATTRIBUTE_TEMPORARY,              { file attributes }
                             0 );                                   { handle to file with attributes to copy }

    { is hInputFile a valid handle? }
    if hInputFile = INVALID_HANDLE_VALUE
      raise Exception.CreateFmt(ROUTINE_ID                                                     + #10 +  #10 +
                                'WinApi function CreateFile returned an invalid handle value'  + #10 +
                                'for the input file * %s *'                                    + #10 + #10 +
                                ErrMsg, [InputFile]);

    { create the appropriate handle for the output file }
    hOutputFile := CreateFile(
                              pOutPutFile,                           { pointer to name of the file }
                              GENERIC_READ or GENERIC_WRITE,         { access (read-write) mode }
                              FILE_SHARE_READ or FILE_SHARE_WRITE,   { share mode }
                              @SecAtrrs,                             { pointer to security attributes }
                              CREATE_ALWAYS,                         { how to create }
                              FILE_ATTRIBUTE_TEMPORARY,              { file attributes }
                              0 );                                   { handle to file with attributes to copy }

    { is hOutputFile a valid handle? }
    if hOutputFile = INVALID_HANDLE_VALUE
      raise Exception.CreateFmt(ROUTINE_ID                                                     + #10 +  #10 +
                                'WinApi function CreateFile returned an invalid handle value'  + #10 +
                                'for the output file * %s *'                                   + #10 + #10 +
                                ErrMsg, [OutputFile]);

    { prepare StartupInfo structure }
    FillChar(StartupInfo, SizeOf(StartupInfo), #0);
    StartupInfo.cb          := SizeOf(StartupInfo);
    StartupInfo.wShowWindow := SW_HIDE;
    StartupInfo.hStdOutput  := hOutputFile;
    StartupInfo.hStdInput   := hInputFile;

    { create the app }
    Result := CreateProcess(nil,                           { pointer to name of executable module }
                            pCommandLine,                  { pointer to command line string }
                            nil,                           { pointer to process security attributes }
                            nil,                           { pointer to thread security attributes }
                            True,                          { handle inheritance flag }
                            CREATE_NEW_CONSOLE or
                            REALTIME_PRIORITY_CLASS,       { creation flags }
                            nil,                           { pointer to new environment block }
                            nil,                           { pointer to current directory name }
                            StartupInfo,                   { pointer to STARTUPINFO }
                            ProcessInfo);                  { pointer to PROCESS_INF }

    { wait for the app to finish its job and take the handles to free them later }
    if Result
        WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
        hAppProcess  := ProcessInfo.hProcess;
        hAppThread   := ProcessInfo.hThread;
      raise Exception.Create(ROUTINE_ID          + #10 +  #10 +
                             'Function failure'  + #10 +  #10 +

    { close the handles
      Kernel objects, like the process and the files we created in this case,
      are maintained by a usage count.
      So, for cleaning up purposes we have to close the handles
      to inform the system that we don't need the objects anymore }
    if hOutputFile <> 0 then CloseHandle(hOutputFile);
    if hInputFile <> 0 then CloseHandle(hInputFile);
    if hAppThread <> 0 then CloseHandle(hAppThread);
    if hAppProcess <> 0 then CloseHandle(hAppProcess);
    { restore the old cursor }
    Screen.Cursor:= OldCursor;


Expert Comment

ID: 9316618
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
Post your closing recommendations!  No comment means you don't care.

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
How can you see what you are working on when you want to see it while you to save a copy? Add a "Save As" icon to the Quick Access Toolbar, or QAT. That way, when you save a copy of a query, form, report, or other object you are modifying, you…
Suggested Courses
Course of the Month9 days, 15 hours left to enroll

569 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question