Выход в DOS, во время выполнения проги

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
electrodrel
Сообщения: 2
Зарегистрирован: 19 окт 2006, 03:13
Контактная информация:

Нужно разработать программу - утилиту копирования файлов. Утилита должна работать аналогично команде COPY MS-DOS.
Так вот, насколько я знаю, для вызова DOS в паскале существует пункт меню DOS Shell, но как выйти в DOS во время выполнения проги?
Заранее спасибо.
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

В стандартном юните Pascal-я DOS есть процедура Exec для запуска внешней программы из своей программы.
Но, насколькоя помню те времена, то для нормальной работы до и после вызова Exec желательно было сделать массу вещей. Поэтому все пользовались процедурой ExecDos из юнита OpDos (TpDos) библиотек Object Professional (Turbo Professional). Есть там также и ShellWithPrompt - для запуска Dos Shell.
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Если нет OpDos, попробую привести текст процедуры ExecDos. Надеюсь, получится скомпилироывать.

Код: Выделить всё

  function ExecDos(Command : string; UseSecond : Boolean; EDP : ExecDosProc) : Integer;
    {-Execute any DOS command. Call with Command = '' for a new shell. If
      UseSecond is false, Command must be the full pathname of a program to be
      executed. EDP is a procedure to display status, save/restore the screen,
 etc. ExecDos return codes are as follows:

       0 : Success
      -1 : Insufficient memory to store free list
      -2 : DOS setblock error before EXEC call
      -3 : DOS setblock error after EXEC call  -- critical error!
      -4 : Insufficient memory to run DOS command
    else   a DOS error code
}

  var
    {Variables for saving and restoring state of system}
    OurInt23 : Pointer;
    OurInt24 : Pointer;
    SaveDta : Pointer;  {!!.01}

    {Variables for managing the heap compression}
    ParasWeHave : Word;
    ParasForDos : Word;
    ParasToKeep : Word;
    OldHeapEnd : Pointer;

    {Variables for parsing the command line}
    BlankPos : Word;
    PathName : string[127];
    CommandTail : string[127];
  begin
    {Current DOS memory allocation read from memory control block}
    ParasWeHave := MemW[Pred(PrefixSeg):3];

    {Calculate amount of memory to give up}
    ParasForDos := Pred(PtrDiff(HeapEnd, HeapPtr) shr 4);

    {Calculate amount of memory to keep while in shell}
    ParasToKeep := ParasWeHave-ParasForDos;

    {See if enough memory to run DOS}
    if (ParasForDos > 0) and (ParasForDos < (MinSpaceForDos shr 4)) then begin
      ExecDos := -4;
      Exit;
    end;

    {Deallocate memory for DOS}
    if not SetBlock(ParasToKeep) then begin
      ExecDos := -2;
      Exit;
    end;

    {Save old end of heap and set new one}
    OldHeapEnd := HeapEnd;
    HeapEnd := HeapPtr;

    {get parameters for Execute}
    if Command = '' then
      UseSecond := True;
    CommandTail := '';
    if not UseSecond {command processor} then begin
      {Command is assumed to be a full pathname for a program}
      BlankPos := Pos(' ', Command);
      if BlankPos = 0 then
        PathName := Command
      else begin
        CommandTail := Copy(Command, BlankPos, Length(Command));
        PathName := Copy(Command, 1, Pred(BlankPos));
      end;
    end
    else begin
      {Pathname is the full pathname for COMMAND.COM}
      PathName := GetEnvironmentString('COMSPEC');

      {if Command is empty, we're doing a shell}
      if Command <> '' then
        {we're asking COMMAND.COM to execute the command}
        CommandTail := '/C '+Command;
    end;

    {Let user routine store and clear the physical screen}
    EDP(ExecSaveScreen, 0);

    {let user routine show status info if entering DOS shell}
    if (Command = '') then
      {Pass user routine the approximate memory available in KB}
      EDP(ExecShowMemory, (ParasForDos-240) shr 6);

    {get current DTA}    {!!.01}
    GetDta(SaveDta);     {!!.01}

    {switch vectors}
    SwapVectors;

    {Call Turbo's EXEC function}
    Exec(PathName, CommandTail);

    {restore vectors}
    SwapVectors;

    {restore DTA}        {!!.01}
    SetDta(SaveDta);     {!!.01}

    {Reallocate memory from DOS}
    if not SetBlock(ParasWeHave) then begin
      ExecDos := -3;
      Exit;
    end;

    {Put heap end back where it was}
    HeapEnd := OldHeapEnd;

    {if not in shell, let user routine allow time to see result}
    if (Command <> '') or (DosError <> 0) then
      EDP(ExecPauseAfterRun, 0);

    {give user routine a chance to restore the screen}
    EDP(ExecRestoreScreen, 0);

    {If we get to here, our function result is in DosError}
    ExecDos := DosError;
  end;
Пример использования:

Код: Выделить всё

  iErr:=ExecDos('comand.com', TRUE, NoExecDosProc);
  if (iErr<> 0) then
    begin
       writeln(#7'Ошибка запуска файла ALL2OEM.EXE N ',iErr);
    end
  else
    writeln('Exit Code: ',DosExitCode);
где NoExecDosProc также определена в OpDos просто как "пустая" процедура, НО с соответсвующим набором параметров,
а ExecDosProc - это описание типа процедуры:

Код: Выделить всё

type
  ExecDosProc = procedure(ActionCode : ActionCodeType; Param : Word);

procedure NoExecDosProc(ActionCode : ActionCodeType; Param : Word);
    {-Do-nothing ExecDosProc}
  begin
  end;
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Ребята, вы куда копаете? Утилита должна работать аналогично COPY, а не использовать её.
Два параметра, пути к файлам. Один открывается, другой создается - и погнали через буфер. Можно еще с тегами че нить понакрутить. Зачем звать COPY, когда такие вещи можно сделать самому.

А вдруг эту утилу будут юзать заместо COPY, если сделать большой буфер она будет значительно быстрее работать. А потом мы еще жалуемся, что у нас софт тормозной...
It's a long way to the top if you wanna rock'n'roll
electrodrel
Сообщения: 2
Зарегистрирован: 19 окт 2006, 03:13
Контактная информация:

Один открывается, другой создается - и погнали через буфер. Можно еще с тегами че нить понакрутить. Зачем звать COPY, когда такие вещи можно сделать самому.
- спасибо, что подсказали вариант попроще. Вообщем усё получилось, если кому-то понадобится, могу выложить.
Ответить