🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.os.msdos.programmer
5 messages
5 total messages Started by Jeff Meyers Tue, 26 Jan 1993 23:13
Help - DOS commands from program...
#7804
Author: Jeff Meyers
Date: Tue, 26 Jan 1993 23:13
25 lines
1554 bytes
I have written a simple installation program in Turbo Pascal and am having
trouble executing DOS commands from within this program.

If the user types "a:install" everything works fine.  But, if they log to
the floppy first, then run install ( A:\>install <cr> ) things choke.

Specifically, the destination directory is not created and so the files
are all copied into a file in the root directory.  I use the Turbo Pascal
command exec() to call the following command:

    \command.com /C md C:\DEST

I also had trouble logging drives and changing directories under program
control, but got around that by haveing the install program create the
appropriate batch file, then executing it...

Question: am I missing something? Why don't the DOS commands work the
same as at the command line??


-- 
============================================================================
| Jeff Meyers      |  jmeyers@ecst.csuchico.edu      | 39x43'N  121x48'W   |
| Chico, Ca 95926  |  KD6DIS@KE6LW.#NOCAL.CA.USA.NA  | Grid: CN80-CM99 ??  |
============================================================================
Re: Help - DOS commands from program...
#7810
Author: G. David Douglas Jr.
Date: Wed, 27 Jan 1993 02:31
56 lines
3189 bytes
jmeyers@ecst.csuchico.edu (Jeff Meyers) writes:

>I have written a simple installation program in Turbo Pascal and am having
>trouble executing DOS commands from within this program.

>If the user types "a:install" everything works fine.  But, if they log to
>the floppy first, then run install ( A:\>install <cr> ) things choke.

>Specifically, the destination directory is not created and so the files
>are all copied into a file in the root directory.  I use the Turbo Pascal
>command exec() to call the following command:

>    \command.com /C md C:\DEST

>I also had trouble logging drives and changing directories under program
>control, but got around that by haveing the install program create the
>appropriate batch file, then executing it...

>Question: am I missing something? Why don't the DOS commands work the
>same as at the command line??

>-- 
>============================================================================
>| Jeff Meyers      |  jmeyers@ecst.csuchico.edu      | 39x43'N  121x48'W   |
>| Chico, Ca 95926  |  KD6DIS@KE6LW.#NOCAL.CA.USA.NA  | Grid: CN80-CM99 ??  |
>============================================================================

Well, ideally I'd like to have more information, but here's a hunch:

Does the floppy disk you're trying to run the utility from have a
copy of COMMAND.COM on it?  If not, and if you're trying to execute
\COMMAND.COM instead of C:\COMMAND.COM, for instance, it probably won't
work -- can't find COMMAND on the floppy disk, so can't execute it.

Also, I don't know which version of Turbo Pascal you're using, but:  does a
command like getenv (or get environment entry) exist in your version?  If so,
you could retrieve the (it _should_ be there) string associated with the
COMSPEC environment variable, and use THAT for the drive-name/directory-path
to a copy of COMMAND.COM to execute.


Just my opinion on what MIGHT be wrong.

One last note:  I once wrote a utility (under Turbo Pascal 3.1 (old, I
know :-)) that does some of the operations (change drive, change
directory, etc.) you describe; problem is, nothing like the  exec  command
was around (had to write my own code to do that).  If I remember correctly,
version 3.1 had a command called  chdir  (change directory) -- does yours?
(Change drive was something else -- I ended up using the DOS-services
(MSDOS ?) function to change disk drive, change file attributes, etc.)
Drop me a line if you'd like a copy of the source code (now just collecting
dust on my disk drive :-).


David Douglas
douglas@usceast.cs.scarolina.edu
Re: Help - DOS commands from program...
#7785
Author: G. David Douglas Jr.
Date: Wed, 27 Jan 1993 04:35
232 lines
8219 bytes
P.S.  This isn't the code I mentioned, but I tried it, and exec'ing 
      COMMAND.COM to change to another directory, then opening a file
      and writing to it DOES cause the file to be created in the 
      changed-to directory, so see what you think.  (This is under
      MS-DOS 4.01). 
      
      (I _HOPE_ this isn't an inappropriate posting for this group!
       If so, my apologies!)


David Douglas
douglas@usceast.cs.scarolina.edu


{ File:  QWERTY.PAS (for lack of a better filename :-) }
program tryit;

{$I EXEC.PAS}

VAR F : TEXT;

BEGIN

  EXEC('C:\COMMAND.COM', '/C CD C:\');
  EXEC('C:\COMMAND.COM', '/C MD QWERTY.DIR');
  EXEC('C:\COMMAND.COM', '/C CD \QWERTY.DIR');
  ASSIGN(F,'QWERTY.OUT');
  REWRITE(F);
  WRITELN(F, 'This the output of QWERTY');
  CLOSE(F);

END.

{ File:  EXEC.PAS }


{----------------------------------------------------------------------------}
{                                                                            }
{     Exec                                                                   }
{                                                                            }
{   This subroutine, given a partial (or full) path-name to a file to be     }
{ executed (but NOT a .BAT file), and a commandline containing the           }
{ parameters to be passed to that program, tries to execute the given        }
{ file with the given parameters.  If an error occurs, an appropriate error  }
{ message is printed.                                                        }
{                                                                            }
{   To execute a particular batch file, specify COMMAND.COM as the program   }
{ to be executed, and '/C batch-file-name' as the commandline.  DON'T TRY    }
{ TO EXECUTE A BATCH FILE DIRECTLY -- THE COMPUTER WILL LOCK UP, AND YOU     }
{ WILL HAVE TO RESET THE COMPUTER!!!                                         }
{                                                                            }
{ ***NOTE*** : Compile to an executable file with a 'O C I 0' option and     }
{ a reasonable 'O C A' value of, for instance, 0800(from the Turbo Pascal    }
{ main menu).  Otherwise, there may not be enough memory available to load   }
{ and execute the requested program.                                         }
{                                                                            }
{                                                                            }
{----------------------------------------------------------------------------}

TYPE _EXECSTRING255_ = STRING[255];

PROCEDURE EXEC(FILENAME, COMMANDLINE : _EXECSTRING255_);

  CONST EOS  = #0;  { End-Of-String }
        BEEP = #7;

        ERROR_MSG : _EXECSTRING255_ =
                    'Error in execution of child process -- try again.';

        ERROR_MESSAGES : ARRAY[1..18] OF _EXECSTRING255_ =
        ( 'Invalid function number.',
          'File not found.',
          'Path not found.',
          'Too many open files (no handles available).',
          'Access denied.',
          'Invalid handle.',
          'Memory control blocks destroyed.',
          'Insufficient memory.',
          'Invalid memory block address.',
          'Invalid environment.',
          'Invalid format.',
          'Invalid access code.',
          'Invalid data.',
          '',            { not used }
          'Invalid drive specified.',
          'Attempted to remove the current directory.',
          'Not same device.',
          'No more files.'
        );

  TYPE ARRTYPE = ARRAY[1..256] OF CHAR;

       PARAMBLOCKTYPE  = RECORD
                           ENV,
                           CMDLINEOFS,
                           CMDLINESEG,
                           FCB1OFS,
                           FCB1SEG,
                           FCB2OFS,
                           FCB2SEG    : INTEGER;
                         END;

       REGISTERS = RECORD
         CASE BOOLEAN OF
           TRUE  : ( AL, AH, BL, BH, CL, CH, DL, DH : BYTE );
           FALSE : ( AX,     BX,     CX,     DX,
                     BP, SI, DI, DS, ES, FLAGS : INTEGER );
         END;

  VAR
      XERROR_MSG  : _EXECSTRING255_;
      ENVIRONMENT : INTEGER ABSOLUTE CSEG:$2C;
      ASCIIZSTR   : ARRTYPE;
      I,J         : INTEGER;

      FCB1,
      FCB2        : ARRAY[1..16] OF BYTE;
      ERRORCODE   : INTEGER;

      PARAMBLOCK  : PARAMBLOCKTYPE;
      R           : REGISTERS;


  BEGIN  { PROCEDURE EXEC }

{ Initialize the FULL error message }

    XERROR_MSG := BEEP + BEEP + BEEP + ERROR_MSG;

{ "Initialize" the two FCBs }

    FOR I := 1 TO 16 DO
      BEGIN
        FCB1[I] := 0;
        FCB2[I] := 0;
      END;

    FOR I := 2 TO 12 DO
      BEGIN
        FCB1[I] := 32;
        FCB2[I] := 32;
      END;

{ Load the ENV, CMDLINESEG, etc., fields of the PARAMBLOCK record with }
{ the appropriate values.                                              }

    WITH PARAMBLOCK DO
      BEGIN
        ENV        := ENVIRONMENT;
        CMDLINESEG := SEG(COMMANDLINE);
        CMDLINEOFS := OFS(COMMANDLINE);
        FCB1SEG    := SEG(FCB1);
        FCB1OFS    := OFS(FCB1);
        FCB2SEG    := SEG(FCB2);
        FCB2OFS    := OFS(FCB2);
      END;

{ Get the given filename-string into ASCIIZ format }

    J := 0;
    FOR I := 1 TO LENGTH(FILENAME) DO
      BEGIN
        J := J + 1;
        ASCIIZSTR[J] := FILENAME[I];
      END;
    J := J + 1;
    ASCIIZSTR[J] := EOS;

{ Initialize the proper register-fields in register-record R. }

    WITH R DO
      BEGIN
        DS := SEG(ASCIIZSTR);
        DX := OFS(ASCIIZSTR);
        ES := SEG(PARAMBLOCK);
        BX := OFS(PARAMBLOCK);
        AH := $4B;              { Execute-child-process service }
        AL := 0;                { Load and execute method       }
      END;

{ Invoke the proper service }

    MSDOS(R);

{ Check the result -- if the Carry bit of FLAGS is set, then an error }
{ occurred -- print the appropriate error message.  Error code is     }
{ found in AX register field.                                         }

    IF (R.FLAGS AND 1) = 1
      THEN BEGIN
             WRITELN(XERROR_MSG);
             WRITELN(ERROR_MESSAGES[R.AX]);
           END;

  END;  { PROCEDURE EXEC }


{----------------------------------------------------------------------------}
{                                                                            }
{     ReturnCode                                                             }
{                                                                            }
{   This subroutine attempts to retrieve the return-code returned by the     }
{ last program that executed.                                                }
{                                                                            }
{----------------------------------------------------------------------------}

FUNCTION RETURNCODE : INTEGER;

  TYPE

       REGISTERS = RECORD
         CASE BOOLEAN OF
           TRUE  : ( AL, AH, BL, BH, CL, CH, DL, DH : BYTE );
           FALSE : ( AX,     BX,     CX,     DX,
                     BP, SI, DI, DS, ES, FLAGS : INTEGER );
         END;

  VAR
      R : REGISTERS;

  BEGIN

  { Initialize the proper register-fields in R }

      R.AH := $4D;            { Fetch-exit-code service }

      MSDOS(R);

      RETURNCODE := R.AL;         { Return the right return-code }

  END; { FUNCTION RETURNCODE }
Re: Help - DOS commands from program...
#7786
Author: Jeff Meyers
Date: Wed, 27 Jan 1993 08:48
30 lines
1792 bytes
In article <douglas.728101903@ebony.cs.scarolina.edu> douglas@cs.scarolina.edu (G. David Douglas Jr.) writes:
.
.
.
>was around (had to write my own code to do that).  If I remember correctly,
>version 3.1 had a command called  chdir  (change directory) -- does yours?
.
.

Yes!!!!  That fixed it!  Don't know why I didn't notice Borland's version
of the chdir, mkdir, rmdir commands...  I guess they included them because
the DOS equivalent is quirky...  I still have to use a batch file to execute
the self-extracting files, though... any ideas on getting redirection to
work under program control?  The files are compressed with the PK version
of self-extracting stuff (forget the name).  The command

     \command.com /C prcmpgm.exe *.* > nul

does not redirect output to nul. All of the unpacking garbage scrolls
across the screen.  Under batch file control, however, works fine.


Thanks again G. David Douglas, Jr!!


-- 
============================================================================
| Jeff Meyers      |  jmeyers@ecst.csuchico.edu      | 39x43'N  121x48'W   |
| Chico, Ca 95926  |  KD6DIS@KE6LW.#NOCAL.CA.USA.NA  | Grid: CN80-CM99 ??  |
============================================================================
Re: Help - DOS commands from program...
#7784
Author: G. David Douglas Jr.
Date: Thu, 28 Jan 1993 03:08
24 lines
1724 bytes
Hmmm -- trying output redirection with the code I posted seems to
work.  Strange thing is, (this is under a SoftPC PC emulator on
a DECstation here at U.S.C., DOS version 3.3) trying to change
drives doesn't work -- yet it does at home under version 4.01!
It's as if drive/directory information is changed in a more
permanent way under version 4.01 than in version 3.3.  (?????)
I'll have to wait till I get home to check things out
further.  With the exec command you're using, do you give it
the name of the file and the parameters to pass to the utility
(e.g.  exec('C:\COMMAND.COM', '/C CD C:\'); )  or does it
look like  exec('C:\COMMAND.COM /C CD C:\');  ?  I suppose what
I'm getting at is that I don't understand how your version of
exec  is executing C:\COMMAND.COM.

As for output redirection under direct program control, that MAY
be possible (probably is) -- I have a book on MASM (Macro
Assembler) programming by Dan Rollins that lists the various
PC-DOS services available.  That may give a way to redirect
utility output from within a program.  I'll let you know
what I find out.


David Douglas
douglas@usceast.cs.scarolina.edu
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads