Board index » delphi » Closing a DOS window in Windows 95?

Closing a DOS window in Windows 95?

I have a DOS program that is called from within a Delphi2 app. I have
worked out how to get the DOS program up and running in a minimized DOS
window with CreateProcess().

The thing I can't figure out is how to close the DOS window once my DOS
program has finished processing? I would appreciate any ideas.  

Thanks ...  

 

Re:Closing a DOS window in Windows 95?


Quote
Troy A. Fortmann wrote:

> I have a DOS program that is called from within a Delphi2 app. I have
> worked out how to get the DOS program up and running in a minimized DOS
> window with CreateProcess().

> The thing I can't figure out is how to close the DOS window once my DOS
> program has finished processing? I would appreciate any ideas.

> Thanks ...

If you are communicating to it through stdio then just send
'Exit'<CRLF>. If not, then use TerminateProcess.

Mark

Re:Closing a DOS window in Windows 95?


Troy A. Fortmann <tfort...@mindspring.com> wrote:

Quote
> I have a DOS program that is called from within a Delphi2 app. I have
> worked out how to get the DOS program up and running in a minimized DOS
> window with CreateProcess().
> The thing I can't figure out is how to close the DOS window once my DOS
> program has finished processing? I would appreciate any ideas.  

Last year there was a discussion about this, unfortunately I can't
remember what the conclusion was. :(
For starters try the code shown below.

Also, my memory is a little rusty but I seem to recall that using
a PIF you can get the window to auto-close??  Worth checking
as that might provide a simple solution.

If the wm_close approach shown in the code below doesn't work
in your case you may need to investigate wm_quit or
DestroyWindow().  You might search
  http://www.dejanews.com/forms/dnq.html
for those topics, especially in the old archive.

See also "Calling CreateProcess() the easy way":
http://www.chamisplace.com/tips/default.asp?d=12/20/96&c=D

------
The following is from LDELPHI.ZIP; available from Delphi Super
Page and its mirrors, eg:
http://sunsite.anu.edu.au/mirrors/delphi/ftp/docs/ldelphi.zip

{This code will launch and close Notepad from a checkbox.
FindWindow is the one to use in Win95 as hInstance will
always be NIL in Win95.  This is so because each program
gets its own space.}

procedure TForm1.CheckBox1Click(Sender: TObject);
var
  NotepadHandle: hWnd;
begin
  if checkbox1.checked then {start/stop checkbox}
    WinExec('c:\windows\notepad.exe c:\autoexec.bat', sw_ShowNormal)
  else begin
    NotepadHandle := FindWindow('Notepad', nil);
    SendMessage(NotepadHandle, wm_Close, 0, 0);
  end;
end;

{ This code came from Lloyd's help file! }

Re:Closing a DOS window in Windows 95?


I use an installation program that is forced to call a DOS program.
Under Windows 95, the DOS program would complete its task in a window
then just stop. I got around the problem by calling the DOS program
with a PIF file rather than with the EXE directly. Now the window
closes normally and the installation can proceed.

Mark Shapiro
info...@swbell.net

Re:Closing a DOS window in Windows 95?


Quote
Mark Bracey <mbra...@interaccess.com> wrote:
>Troy A. Fortmann wrote:

>> I have a DOS program that is called from within a Delphi2 app. I have
>> worked out how to get the DOS program up and running in a minimized DOS
>> window with CreateProcess().

>> The thing I can't figure out is how to close the DOS window once my DOS
>> program has finished processing? I would appreciate any ideas.

>> Thanks ...
>If you are communicating to it through stdio then just send
>'Exit'<CRLF>. If not, then use TerminateProcess.
>Mark

    The trick is....dont DIRECTLY startup the DOS program...
create a "shortcut' to the program and start the shortcut.
The shortcut has properties...such as automatically closing
the window when the program ends.

Re:Closing a DOS window in Windows 95?


On Fri, 21 Mar 1997 21:23:12 -0600, Mark Bracey

Quote
<mbra...@interaccess.com> wrote:
>If you are communicating to it through stdio then just send
>'Exit'<CRLF>. If not, then use TerminateProcess.

And how is one to know if the dos application is finished?

Re:Closing a DOS window in Windows 95?


I have a program which executes a DOS program and found that if I
redirected standard out in the CreateProcess call to a pipe I could use
WaitForSingleObject to know when the application had terminated. If I
didn't redirect stdout the program would hang waiting for the close which
never came.

However, I have a problem with this since I need to read from this pipe
(which is connected to the standard output of the DOS application). This
works OK until the DOS application has finished writing at which point the
ReadFile never returns. Is there a way of determining whether input is
available on a pipe (anonymous rather than named file).

The following is an extract on how to create the pipe and then attach it to
the standard output of the DOS application. I place it here for two
reasons: Firstly to help anyone trying to do the same; secondly because
someone who knows the API better than I do might spot something which would
make the ReadFile return when the other end of the pipe has terminated:

var
    // Definition of the window for the new process
   StartUpInfo : TStartupInfo;
   ProcessInfo : TProcessInformation;
   CommandLine : String;
   FailString  : String;

   // Bits and bobs for communicating with the child process
   Read_FD         : THandle;
   Write_FD        : THandle;
   Pipe_Attributes : TSecurityAttributes;
   Buffer          : array [0 .. 1023] of Char;
   Bytes_Read      : Integer;
   Still_Going     : Boolean;
   Process_Status  : Integer;

begin

    // Disregard this line - it is something my application does
    // unrelated to the creation of the process.
    if CurrentFile <> '' then begin

     CommandLine := 'C:\ Some Executable or Other';

      // Create a pipe to communicate with the DOS application
      Pipe_Attributes.nLength := SizeOf (TSecurityAttributes);
      Pipe_Attributes.lpSecurityDescriptor := nil;
      Pipe_Attributes.bInheritHandle := True;

      if not CreatePipe (Read_FD,
                         Write_FD,
                         @Pipe_Attributes,
                         0) then begin

         FailString := 'Error ' + IntToStr (GetLastError);

         Application.MessageBox (PChar (FailString),
                                 'No pipe!',
                                 mb_ok);
         Exit;
      end;

      // Fill in the startup info to hide the window and use the
      // write file descriptor for the pipe as standard output. Note
      // that by specifying the input and error file descriptors as
      // invalid, the defaults get used.
      FillChar(StartUpInfo, SizeOf (TStartupInfo), 0);
      StartUpInfo.cb := SizeOf (TStartupInfo);
      StartUpInfo.dwFlags := STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES;
      StartUpInfo.wShowWindow := SW_SHOWNORMAL;
      StartUpInfo.wShowWindow := SW_HIDE;
      StartUpInfo.hStdInput := INVALID_HANDLE_VALUE;
      StartUpInfo.hStdOutput := Write_FD;
      StartUpInfo.hStdError := INVALID_HANDLE_VALUE;

      // Create a process to run the assembler
      if not CreateProcess
         (nil,                     // Application Name
          PAnsiChar (CommandLine),
          nil,                     // Process attributes
          nil,                     // Thread attributes
          True,  0,                  // Inherit handles
          //DETACHED_PROCESS,        // Creation flags
          nil,                     // environment
          nil,                     // current directory
          StartUpInfo,
          ProcessInfo) then begin

          FailString := 'Error ' + IntToStr (GetLastError);

          Application.MessageBox (PChar (FailString),
                                  PChar (CommandLine),
                                  mb_ok);
      end else begin

         // Read data until the application has finished
         Still_Going := True;
         while Still_Going do begin

            FillChar(Buffer, SizeOf (Buffer), 0);
            if not ReadFile (Read_FD,
                             Buffer,
                             256,
                             Bytes_Read,
                             nil) then

               Still_Going := False

            else if Bytes_Read = 0 then

               Still_Going := False

            else begin

               FailString := 'Bytes: ' + IntToStr (Bytes_Read);
               Application.MessageBox (@Buffer, 'Read', mb_OK);

            end;

            // Check if application has terminated
            if not GetExitCodeProcess (ProcessInfo.hProcess,
                                       Process_Status) then

               Still_Going := False

            else

               if Process_Status <> STILL_ACTIVE then

                  Still_Going := False;

         end;

         // The process was created. Wait for it to complete
         WaitForSingleObject (ProcessInfo.hProcess,
                              INFINITE);

         // Close the process
         CloseHandle (ProcessInfo.hProcess);

         // At this point there might be data left in the pipe. But if I
         // do a ReadFile and there isn't the process hangs. HELP!
      end;
   end;
end;

Bill Mothershead <m...@primenet.com> wrote in article
<5hfafe$...@nnrp1.news.primenet.com>...

Quote
> Mark Bracey <mbra...@interaccess.com> wrote:

> >Troy A. Fortmann wrote:

> >> I have a DOS program that is called from within a Delphi2 app. I have
> >> worked out how to get the DOS program up and running in a minimized
DOS
> >> window with CreateProcess().

> >> The thing I can't figure out is how to close the DOS window once my
DOS
> >> program has finished processing? I would appreciate any ideas.

> >> Thanks ...

> >If you are communicating to it through stdio then just send
> >'Exit'<CRLF>. If not, then use TerminateProcess.

> >Mark

>     The trick is....dont DIRECTLY startup the DOS program...
> create a "shortcut' to the program and start the shortcut.
> The shortcut has properties...such as automatically closing
> the window when the program ends.

Other Threads