From: d9mikael@dtek.chalmers.se (Mikael Wahlgren)
Newsgroups: comp.os.os2.programmer
Subject: Executing DOS commands in OS/2 1.3
Date: 8 Apr 92 21:13:18 GMT
Article-I.D.: chalmers.10900
Organization: Chalmers University of Technology

On request, I will post a Modula-2 example on how to start a DOS command
in the OS/2 1.3 DOS-box.  This example uses the DOS.SYS driver to start
a DOS-command, switches to the DOS-session, and when the command is finished
switches back to the original session.

Mikael Wahlgren


MODULE DosCmd2;

IMPORT FIO, Dos, Str, Win;

FROM OS2DEF   IMPORT HWND, HAB;

PROCEDURE SwitchToDos;
  VAR
    ReturnCode      : CARDINAL;
    GlobalInfoSel   : CARDINAL;
    LocalInfoSel    : CARDINAL;
    GlobalInfoSeg   : POINTER TO Dos.GINFOSEG;
    LocalInfoSeg    : POINTER TO Dos.LINFOSEG;
    FgHandle        : Win.HSWITCH;
    DosHandle       : CARDINAL;
    SwitchBuffer    : RECORD
                        SwitchCount     : CARDINAL;
                        SwitchEntry     : ARRAY [1..100] OF RECORD
                                            SwitchHandle    : Win.HSWITCH;
                                            SwitchControl   : Win.SWCNTRL;
                                          END;
                      END;
    Count           : CARDINAL;
  BEGIN

    (* First we get the foreground process ID from the local info seg *)

    Dos.GetInfoSeg(GlobalInfoSel,LocalInfoSel);
    GlobalInfoSeg := [GlobalInfoSel:0];
    LocalInfoSeg  := [LocalInfoSel:0];
    FgHandle      := Win.QuerySwitchHandle(HWND(0),LocalInfoSeg^.pidCurrent);

    (* Get the switch list *)

    Count := Win.QuerySwitchList(HAB(0),ADR(SwitchBuffer),SIZE(SwitchBuffer));

    (* Find the switch entry containing the string 'DOS' *)

    WHILE ((Count <> 0) AND (Str.Compare(SwitchBuffer.SwitchEntry[Count].SwitchControl.Swtitle,'DOS') <> 0)) DO
      DEC(Count);
    END;

    IF Count <> 0 THEN

      (* We found a switch entry with the string 'DOS'.  Switch to it *)

      DosHandle := GlobalInfoSeg^.pidForeground;
      Win.SwitchToProgram(SwitchBuffer.SwitchEntry[Count].SwitchHandle);

      (* Loop slowly until we have detected another foreground PID, this
         means that OS/2 has switched to the DOS-session *)

      REPEAT
        Dos.Sleep(100);
      UNTIL DosHandle <> GlobalInfoSeg^.pidForeground;
      DosHandle := GlobalInfoSeg^.pidForeground;

      (* Loop slowly once again until we have detected yet another
         foreground PID, this means that OS/2 has switched to the desktop
         after finishing the DOS command *)

      REPEAT
        Dos.Sleep(100);
      UNTIL DosHandle <> GlobalInfoSeg^.pidForeground;

      (* Switch back to our original session *)

      Win.SwitchToProgram(FgHandle);
    END;
  END SwitchToDos;


PROCEDURE DosCmd(Txt : ARRAY OF CHAR);
  VAR
    DosDrv          : FIO.File;
    CmdBuffer       : ARRAY [1..128] OF CHAR;
  BEGIN

    (* Open DOS.SYS driver and write command information *)

    Str.Concat(CmdBuffer, CHR(128) + CHR(32), Txt);
    Str.Append(CmdBuffer, CHR(13));
    DosDrv := FIO.Create('DOS$');
    FIO.WrStr(DosDrv, CmdBuffer);
    FIO.WrChar(DosDrv, CHR(0));
    FIO.Close(DosDrv);
    SwitchToDos;
  END DosCmd;

BEGIN
  DosCmd('DIR');
END DosCmd2.


Mikael Wahlgren      d9mikael@dtek.chalmers.se