Board index » delphi » Run ms-dos command in Pascal program

Run ms-dos command in Pascal program

Can anyone tel me how can i execute a ms-dos command in a Pascal program.

Tanks in advanced.

Jo?o Pedro
j....@usa.net

 

Re:Run ms-dos command in Pascal program


Quote
"Jo?o Pedro" wrote:
> Can anyone tel me how can i execute a ms-dos command in a Pascal program.

> Tanks in advanced.

> Jo?o Pedro
> j....@usa.net

FAQ

Re:Run ms-dos command in Pascal program


In article <73gtfp$9g...@duke.telepac.pt>, "Jo?o Pedro" <j....@usa.net>
wrote:

Quote
>Can anyone tel me how can i execute a ms-dos command in a Pascal
>program.

Exec()

--

= Blackdeath - s_honsber...@13usa.net
== http://sprk.com/blackdeath
=== ICQ UIN # 3484915
==== Remove 'thir{*word*249}' to reply

... Redneck INTERNET ADDRESS:  Third dirt road, hang a left...
-!- GOPGP/2 v1.20

Re:Run ms-dos command in Pascal program


Quote
>>Can anyone tel me how can i execute a ms-dos command in a Pascal
>>program.

>Exec()

I thought that too, but now I try to delete a File

A I've a variable (string) containig the complete pathname
e.g.  PathName := 'c:\tmp\x.txt';

and then

exec (del, PathName);

but after that, the file still exists. Whats wrong?

Thanks for any hint
Andy Vontobel

Re:Run ms-dos command in Pascal program


Quote
In article <73gtfp$9g...@duke.telepac.pt>, Jo?o Pedro <j....@usa.net> wrote:
>Can anyone tel me how can i execute a ms-dos command in a Pascal program.

Use the following and then just issue for example
Shell('edit c:\autoexec.bat');

Unit Xheap;

Interface

uses dos;

{$ifdef msdos }

{if protected mode one just provides push and shell(). The swamping is
 automatic in PM }

type string128=string[128];

procedure exec(const com,par:string128);
Function MaxProg:word;  { kilobytes }

Const Swapstack{:boolean}=true;    { Change if you wish }
      UseXMS{:boolean}=true;       { Swap to XMS }
      XmsInts{:boolean}=true;      { Use XMS for interrupts }
      Usedisk{:boolean}=true;      { Swap to disk (c:\) }

{$endif}

const Enough:word=736;             { Don't swap to disk is there is enough }
                                   { memory (KB) available }

{Note value 736 means swap always to disk. 0 means never. This has nothing
 to do with XMS swapping }

Const freeenv:word=300; { amount of free environment for shell/push }

Procedure Shell(const st:string);
Procedure Push;

Const errorcode=233;  { uses codes 233-236}

{ The swapping is done as follows:

Is there enough XMS to Swap the heap (and part of the stack)?
If there is then write the heap to the XMS
else
  if DiskUse is Disabled then Use What XMS one can get
  else
    Is if there "enough" (see above) free without swapping?
    if there is then do not swap, just use unused part of the heap
    else
      is there enough space to write the heap to disk
      if there is then write it to disk
      else do not swap
Is there enough XMS (1KB) to store the interrupts?
if there is use XMS for ints
else
  use conventional memory for ints
  if there is not enough free, set doserror=8 and do not exec()

Note:

  When one swaps to disk one always swaps all or nothing.
  If disk use is enabled (as it is normally) one does not swap
  partial heap to XMS. Interrupts are stored either to XMS or base
  memory, never to disk.

  The file is stored on the root of the C-drive. The file name is in form of
  xheapX.swp where X is 0..999. If you reboot or power down while the
  program called with exec() is running the temporary file will be left to
  disk until manually deleted. You may put:

  if exist c:\xheap*.swp del c:\xheap*.swp >nul

  in your autoexec.bat to avoid that.

  Any attempt to tamper with the temporary file while the program called
  with exec() is running can cause a crash or any other unpleasant result.
  Just do not do it.

Memory map:

                          SS:0 SP      HO        HP           HE
                            v   v      v         v            v
     |--|--------------|----|-----|----|----------------------|
     PSP Code segments  Data Stack Over  Heap
                                   lay

SP: Stack pointer (CPU register)
HO: HeapOrg
HP: HeapPtr
HE: HeapEnd (typically at 640K)

If SP is large (>1500)

  1) Move SP to 1500
  2) write between old SP and Heapptr to XMS/Disk:

                                orig
                             SP SP     HO        HP           HE
                             v  v      v         v            v
     |--|--------------|----|---XX|XXXX|XXXXXXXXXX------------|
     PSP Code segments  Data Stack Over Heap
                                   lay

Free memory after SP for the program to be executed:

                             SP
                             v
     |--|--------------|----|-|
     PSP Code segments  Data Stack

If SP is small (<1500)

   write between SP and Heapptr to XMS/Disk:

                             SP        HO        HP           HE
                             v         v         v            v
     |--|--------------|----|-XXXX|XXXX|XXXXXXXXXX------------|
     PSP Code segments  Data Stack Ovl  Heap

Interrupt vectors are stored either on XMS or right after SP:

                             SP
                             v
     |--|--------------|----|-III|
     PSP  Code segments Data Stack Ovl  Heap

Note unused parts of the stack or heap change their values.

Interrupt vectors are saved so that possible TSRs can be unloaded
safely.

Quote
}

Implementation

{$ifdef msdos}

const spmin=1500;

{-------------------------- XMS routines -----------------------}

Var Handle:word;
    intHandle:word;
    xmsentry:pointer;

Procedure GetXMSentry; assembler;
             asm
             xor ax,ax
             mov word ptr xmsentry,ax
             mov word ptr xmsentry+2,ax

             mov ax,4300h
             int 2fh
             cmp al,80h
             jne @out
             mov ax,4310h
             int 2fh
             mov word ptr xmsentry,bx
             mov word ptr xmsentry+2,es
      @out:
             end;

Function FreeXms:word; assembler;
         asm
         mov ax,word ptr xmsentry
         or ax,word ptr xmsentry+2
         jz @out
         mov ah,8
         call xmsentry
@out:
         End;

Function XInit(Kb:word;var handle:word):byte; assembler;
         asm
         mov ax,word ptr xmsentry
         or ax,word ptr xmsentry+2
         mov al,255
         jz @out
         mov dx,kb
         mov ah,9
         call XmsEntry
         cmp ax,1
         mov al,bl
         jne @out
         xor al,al
         les di,handle
         mov es:[di],dx
  @out:
         end;

Procedure XWrite(handle:word;p:pointer; count:longint);
type  emm=record
            count:longint;
            zero:word;
            P:pointer;
            handle:word;
            Pos:longint;
          End;
const e:emm=(count:0;zero:0;p:nil;handle:0;pos:0);
begin
  e.count:=count;
  e.p:=p;
  e.handle:=handle;
  asm
   mov ah,$b
   mov si,offset e
   call XmsEntry
  end;
End;

Procedure XRead(handle:word;p:pointer; count:longint);
type  emm=record
            count:longint;
            handle:word;
            Pos:longint;
            zero:word;
            P:pointer;
          End;
const e:emm=(count:0;handle:0;pos:0;zero:0;p:nil);
begin
  e.count:=count;
  e.p:=p;
  e.handle:=handle;
  asm
   mov ah,$b
   mov si,offset e
   call XmsEntry
  end;
End;

procedure XDone(handle:word); assembler;
  asm
  mov dx,handle
  mov ah,$a
  call xmsentry
  end;

{-----------------------  End XMS routines ----------------------- }

var xmsinuse:boolean;
    ints:word;   { segment address }

Type Words=Record
             lo,hi:Word;
           End;

     pp=^longint;

Function p2i(p:pointer):longint; assembler;
         asm
         mov ax,word ptr p+2
         mov dx,ax
         {$ifopt g+}
         shl ax,4
         shr dx,12
         {$else}
         mov cl,4;  shl ax,cl
         mov cl,12; shl dx,cl
         {$endif}
         add ax,word ptr p
         adc dx,0
         end;

function i2p(i:longint):pointer; assembler;
         asm
         mov ax,word ptr i
         mov dx,word ptr i+2
         mov bx,ax
         {$ifopt g+}
         shl dx,12
         shr bx,4
         {$else}
         mov cl,12; shl dx,cl
         mov cl,4;  shr bx,cl
         {$endif}
         and ax,15
         add dx,bx
         end;

{ ------------------------ File IO routines ----------------------- }

var fname:string[14];

{$i-}
Procedure Fwrite(p:pointer; len:longint);
var fp:file;
    i:integer;
const bsize=63*1024;
begin
  assign(fp,fname);
  rewrite(fp,1);
  while len>bsize do begin
    blockwrite(fp,p^,bsize);
    dec(len,bsize);
    inc(words(p).hi,bsize shr 4);
  End;
  blockwrite(fp,p^,len);
  close(fp);
  i:=ioresult;
  if i>0 then begin
     erase(fp);
     inoutres:=i;
  End;

End;

{$i+}

Procedure Fread(p:pointer; len:longint);
var fp:file;
const bsize=63*1024;
begin
  assign(fp,fname);
  reset(fp,1);
  while len>bsize do begin
    blockread(fp,p^,bsize);
    dec(len,bsize);
    inc(words(p).hi,bsize shr 4);
  End;
  blockread(fp,p^,len);
  close(fp);
  erase(fp);
End;

Procedure GetTempName;
var rg:registers;
    s:string[14];
    i:0..1000;
    fp:file;
const first:word=0;
begin
  {$i-}
  i:=first;
  repeat
    str(i,s);
    s:='c:\xheap'+s+'.swp';
    assign(fp,s);
    reset(fp,1);
    close(fp);
    inc(i);
  until (i>=1000) or (ioresult<>0);
  if i>=1000 then fname:='..error'
             else fname:=s;
  first:=i-1;
  {$i+}
end;

{----------------------------------------------------------------}

var startptr:pointer;  { Start of the area swappted to XMS }
    len:longint;       { no of bytes in XMS }

{ Startptr: Start of the area to be written to XMS
  Endptr: End of area to be kept }

procedure HeapOut(stptr,endptr:pointer);
var rg:registers;
    fx:word;
Begin
  ints:=0;
  startptr:=stptr;

  inc(words(startptr).hi,words(startptr).lo shr 4);
  words(startptr).lo:=words(startptr).lo and 15;

  inc(words(endptr).hi,words(endptr).lo shr 4);
  words(endptr).lo:=words(endptr).lo and 15;

  len:=p2i(heapptr)-p2i(startptr);
  if usedisk then fname:='';
  if usexms and (xinit((len+1023) shr 10,handle)=0) then begin
     xwrite(handle,startptr,len);
     xmsinuse:=true;                           { Write the heap into XMS }
  End
  else begin
     if usexms then fx:=freexms;        { lets get what XMS we can get }
     if not usedisk and usexms and (fx>0) and (xinit(fx,handle)=0) then begin
        len:=longint(fx)*1024;
        startptr:=i2p(p2i(heapptr)-len);
        xwrite(handle,startptr,len);
        xmsinuse:=true;
        endptr:=startptr;
     end else begin
               {$i-}
               xmsinuse:=false;
               if usedisk and
                 (words(heapend).hi-words(heapptr).hi<enough*64+67) then
               begin
                  endPtr:=startptr;
                  Gettempname;
                  fwrite(startptr,len);
                  if ioresult<>0 then begin
                     fname:='';
                     Endptr:=HeapPtr;
                  End
               end
               else begin
                 fname:='';
                 EndPtr:=HeapPtr;
               End
               {$i+}
     End;
  End;

  rg.bx:=words(Endptr).hi-prefixseg+65;
  if
...

read more »

Re:Run ms-dos command in Pascal program


Quote
Andi Vontobel wrote:
> I thought that too, but now I try to delete a File

> A I've a variable (string) containig the complete pathname
> e.g.  PathName := 'c:\tmp\x.txt';

> and then

> exec (del, PathName);

> but after that, the file still exists. Whats wrong?

In case you got the error message "Bad command or file name": it should
have been exec('del ', pathname);

Maybe you did not specify a stack size. Use the compiler directive {$M
8192,0,0} for example. (I don't know how this influences
dynamic variables you may also have declared)-

If this is not the reason either, check the DosError variable right
after Exec.

Oh, one final thing. Maybe the files was write-protected or hidden or
whatever.

Re:Run ms-dos command in Pascal program


On Thu, 26 Nov 1998 13:08:58 +0100, Frederic <frede...@rz-online.de>
wrote:

Quote
> > A I've a variable (string) containig the complete pathname
> > e.g.  PathName := 'c:\tmp\x.txt';
> > and then
> > exec (del, PathName);
> > but after that, the file still exists. Whats wrong?
> In case you got the error message "Bad command or file name": it should
> have been exec('del ', pathname);
> Maybe you did not specify a stack size. Use the compiler directive {$M
> 8192,0,0} for example. (I don't know how this influences
> dynamic variables you may also have declared)-
> If this is not the reason either, check the DosError variable right
> after Exec.
> Oh, one final thing. Maybe the files was write-protected or hidden or
> whatever.

I'd propose that he rather should use the correct syntax to execute an
internal DOS command;

{$M 8192,0,0}
uses dos;
var
  pathname:string;
begin
  pathname:= 'c:\tmp\x.txt';
  exec(getenv('COMSPEC'),'/C del '+pathname);
end.

Regards
Horst

Re:Run ms-dos command in Pascal program


Quote
Horst Kraemer wrote:

[...]

Quote
> > Oh, one final thing. Maybe the files was write-protected or hidden or
> > whatever.

> I'd propose that he rather should use the correct syntax to execute an
> internal DOS command;

> {$M 8192,0,0}
> uses dos;
> var
>   pathname:string;
> begin
>   pathname:= 'c:\tmp\x.txt';
>   exec(getenv('COMSPEC'),'/C del '+pathname);
> end.

> Regards
> Horst

Working with files can be tricky, since so many thing can go wrong.

Why not use Pascal, which would be faster and gives better error
checking?

You could use something like this:

  procedure testerase;

  var
    attr    : word;
    fname   : pathstr;
    NewFile : file;

    begin
      fname := 'C:\WINDOWS\WIN.COM';

      assign(NewFile, fname);

  {$I-}
      GetFattr(NewFile, attr);          {check for read/only attribute}

      if (DosError > 0) then
      begin
        writeln('Cannot find ' + fname);
        exit;
      end;

      if (attr and ReadOnly <> 0) then    {if R/O then set to Archive}
      begin
        SetFattr(NewFile, Archive);

        if (DosError > 0) then
        begin
          writeln('Cannot set file attribute for ' + fname);
          exit;
        end;
      end;

      erase(NewFile);                   {do the deed}
  {$I+}

      if (IOResult > 0) then         {got an error}
      begin
        writeln('Cannot erase ' + fname);
        exit;
      end;
    end;

Best Regards,

Michael R. Monett,
Automated Production Test
mailto:a...@csolve.net

Re:Run ms-dos command in Pascal program


Re:Run ms-dos command in Pascal program


Actually, that routine was pretty dumb. It would leave error-checking
turned off if an error occurred. See what I mean about file handling
being tricky!

The following should be better:

  procedure testerase;

  var
    attr    : word;
    fname   : pathstr;
    NewFile : file;

    begin
      fname := 'C:\WINDOWS\WIN.COM';

      assign(NewFile, fname);

  {$I-}
      GetFattr(NewFile, attr);          {check for read/only attribute}
  {$I+}

      if (DosError > 0) then
      begin
        writeln('Cannot find ' + fname);
        exit;
      end;

      if (attr and ReadOnly <> 0) then  {if R/O then set to Archive}
      begin
  {$I-}
        SetFattr(NewFile, Archive);
  {$I+}

        if (DosError > 0) then
        begin
          writeln('Cannot set file attribute for ' + fname);
          exit;
        end;
      end;

  {$I-}
      erase(NewFile);                   {do the deed}
  {$I+}

      if (IOResult > 0) then            {got an error}
      begin
        writeln('Cannot erase ' + fname);
        exit;
      end;
    end;

Re:Run ms-dos command in Pascal program


Re:Run ms-dos command in Pascal program


In article <365CF986.531C4...@gmx.net>,
Andi Vontobel  <andi.vonto...@gmx.net> wrote:

Quote
>>>Can anyone tel me how can i execute a ms-dos command in a Pascal
>>>program.

>>Exec()
>I thought that too, but now I try to delete a File

>A I've a variable (string) containig the complete pathname
>e.g.  PathName := 'c:\tmp\x.txt';

>and then

>exec (del, PathName);

What is that "del"??? You need to give exec() the full path name of the
program that is to be executed.

Osmo

Re:Run ms-dos command in Pascal program


JRS:  In article <365CF986.531C4...@gmx.net> of Thu, 26 Nov 1998
07:47:34 in news:comp.lang.pascal.borland, Andi Vontobel

Quote
<andi.vonto...@gmx.net> wrote:
>>>Can anyone tel me how can i execute a ms-dos command in a Pascal
>>>program.

>>Exec()
>I thought that too, but now I try to delete a File

>A I've a variable (string) containig the complete pathname
>e.g.  PathName := 'c:\tmp\x.txt';

>and then

>exec (del, PathName);

>but after that, the file still exists. Whats wrong?

>Thanks for any hint

Hint : TSFAQP #9.  

What you wrote should not compile ("del"), and, if you had used "'del'",
you would IIRC need del.com or del.bat (neither of which normally exist)
in the current directory.

--
John Stockton, Surrey, UK.    j...@merlyn.demon.co.uk    Turnpike v4.00    MIME.
  Web <URL: http://www.merlyn.demon.co.uk/> - TP/BP/&c. FAQqish topics & links.
  Timo's TurboPascal <A HREF="ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip">FAQ</A>.
  <A HREF="http://www.merlyn.demon.co.uk/clpb-faq.txt">Mini-FAQ</A> of c.l.p.b.

Re:Run ms-dos command in Pascal program


On Thu, 26 Nov 1998 14:35:31 +0000, Dr John Stockton

Quote
<j...@merlyn.demon.co.uk> wrote:
> JRS:  In article <365CF986.531C4...@gmx.net> of Thu, 26 Nov 1998
> 07:47:34 in news:comp.lang.pascal.borland, Andi Vontobel
> <andi.vonto...@gmx.net> wrote:
> >>>Can anyone tel me how can i execute a ms-dos command in a Pascal
> >>>program.

> >>Exec()
> >I thought that too, but now I try to delete a File

> >A I've a variable (string) containig the complete pathname
> >e.g.  PathName := 'c:\tmp\x.txt';

> >and then

> >exec (del, PathName);

> >but after that, the file still exists. Whats wrong?

> >Thanks for any hint

> Hint : TSFAQP #9.  

> What you wrote should not compile ("del"), and, if you had used "'del'",
> you would IIRC need del.com or del.bat (neither of which normally exist)
> in the current directory.

Much worse. These first parameter of exec is taken _verbose_ without
implicitly searching for .bat .com .exe with the indicated name. This
is a COMMAND.COM service only. EXEC calls DOS-EXEC directly without
using this ability of COMMAND.COM

It would work only if there would be a file named DEL (without
extension) which is a file in COM or EXE format. An existing DEL.EXE
would be ignored as long as you don't rename it to DEL ;-)

Regards
Horst

Re:Run ms-dos command in Pascal program


Go to page: [1] [2] [3]

Other Threads