home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / execdemo.zip / runprog.c < prev    next >
Text File  |  1995-07-17  |  10KB  |  324 lines

  1. /*
  2.  * RUNPROG.C
  3.  * Copyright 1994 Bryan Walker DBA WalkerWerks.  All rights reserved.
  4.  *
  5.  * Examples of using DosStartSession and WinStartApp API calls.
  6.  *
  7.  * This sample is provided to help illustrate examples for the class
  8.  * "Executing Programs in OS/2" for ColoradOS/2 1994.  The code is for
  9.  * example purposes only and not as a teaching tool for general programming principals.
  10.  * The author has no liability for any use of the code either private or commercial,
  11.  * or for any damages arrising from such use.
  12.  *
  13.  */
  14. #define INCL_DOS
  15. #define INCL_DOSERRORS
  16. #define INCL_PM
  17. #include <os2.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <memory.h>
  22. #include <ctype.h>
  23.  
  24.  
  25. char *CsvTok(char *string1) ;
  26.  
  27. /*
  28.  * This function demonstrates using DosStartSession to execute
  29.  * programs.
  30.  */
  31. ULONG StartAppDos(CHAR *app, CHAR *parm, CHAR *dir, CHAR *env, SHORT type, BOOL activate, CHAR *queue)
  32. {
  33. CHAR  homedir[CCHMAXPATH], buff1[CCHMAXPATH], finalenv[600], *ptrenv = finalenv, *tokptr ;
  34. CHAR  ObjBuf[100], Drive[2], *buff2 ;
  35. ULONG len, action, drvnum, drvmap ;
  36. APIRET aprc ;
  37. STARTDATA StartData ;
  38. ULONG SessionID ;
  39. PID   pid ;
  40. BOOL  SetDrive = FALSE ;
  41. HSWITCH hswitch ;
  42.  
  43. memset(&StartData, 0, sizeof(StartData)) ;
  44. StartData.Length = sizeof(StartData);     /* Length of STARTDATA structure */
  45. StartData.Related = SSF_RELATED_CHILD;    /* child so OS/2 will notify of termination.*/
  46. StartData.FgBg = SSF_FGBG_BACK;           /* start in background */
  47. StartData.TraceOpt = SSF_TRACEOPT_NONE;   /* no debug tracing enabled */
  48. StartData.PgmTitle = NULL;                /* no default title. */
  49. StartData.TermQ = queue ;                 /* passed notification queue. */
  50. StartData.InheritOpt = SSF_INHERTOPT_PARENT; /* inherit our environment for working directory */
  51. StartData.IconFile = 0;                   /* no specified icon file */
  52. StartData.PgmHandle = 0;                  /* OS/2 1.3 holdover not used */
  53. StartData.PgmControl = SSF_CONTROL_VISIBLE ; /* visible on desktop */
  54. StartData.ObjectBuffer = ObjBuf;          /* error buffer */
  55. StartData.ObjectBuffLen = 100;            /* size of the error buffer */
  56. StartData.PgmName = app ;                 /* program name */
  57. StartData.PgmInputs = parm ;              /* command line for program */
  58.  
  59. /*
  60.  * Pass environment variables in CSV format.  If not null
  61.  * parse out the individual variables and build the
  62.  * environment string.  It is formatted with each environment=value
  63.  * statement separated by a NULL character.  The final variable is
  64.  * followed by two NULL characters.
  65.  *
  66.  * i.e. PATH=C:\\;'\0'LIB=C:\\;'\0''\0'
  67.  *
  68.  */
  69. if(env != NULL && *env != 0)
  70.    {
  71.    memset( finalenv, 0, sizeof(finalenv)) ;
  72.    StartData.Environment = finalenv ;
  73.    if( ( tokptr = CsvTok( env )) != NULL) /* CsvTok is a CSV format tokenizer */
  74.       {
  75.       do
  76.          {
  77.          strcpy( ptrenv, tokptr ) ;
  78.          ptrenv += strlen(tokptr) + 1;
  79.          tokptr = CsvTok( NULL ) ;
  80.          }while ( tokptr != NULL ) ;
  81.       }
  82.  
  83.    }
  84. /*
  85.  * Convert the passed type into the appropriate PM type
  86.  */
  87. switch(type)
  88.    {
  89.    case 0:
  90.       StartData.SessionType = PROG_PM ;
  91.       break;
  92.    case 1:
  93.       StartData.SessionType = PROG_WINDOWABLEVIO ;
  94.       break;
  95.    case 2:
  96.       StartData.SessionType = PROG_FULLSCREEN ;
  97.       break;
  98.    case 3:
  99.       StartData.SessionType = PROG_WINDOWEDVDM ;
  100.       break;
  101.    case 4:
  102.       StartData.SessionType = PROG_VDM ;
  103.       break;
  104.    case 5:
  105.       /*
  106.        * For windows applications using DosStartSession
  107.        * you must call WINOS2.COM or WIN.COM and make the
  108.        * desired program the first commandline parameter followed
  109.        * by the programs commandline.
  110.        *
  111.        * First allocate a buffer for the new commandline.
  112.        * then copy the program name and real commandline
  113.        * into the buffer to create the new commandline.
  114.        * Finally set the program name to win.com.  WINOS2.COM
  115.        * is also on the computer as WIN.COM so use that instead
  116.        * so the program will also work in OS/2 for Windows products.
  117.        */
  118.       len = strlen( app ) + strlen ( parm ) + 2 ;
  119.       buff2 = malloc( len ) ;
  120.       if(buff2 == NULL )
  121.          return NULLHANDLE ;
  122.       sprintf( buff2, "%s %s", app, parm ) ;
  123.       strcpy( buff1, "win.com") ;
  124.       StartData.PgmName = buff1 ;
  125.       StartData.PgmInputs = buff2 ;
  126.       StartData.SessionType = PROG_31_STDSEAMLESSCOMMON ;
  127.       break;
  128.    case 6:
  129.       len = strlen( app ) + strlen ( parm ) + 2 ;
  130.       buff2 = malloc( len ) ;
  131.       if(buff2 == NULL )
  132.          return NULLHANDLE ;
  133.       sprintf( buff2, "%s %s", app, parm ) ;
  134.       strcpy( buff1, "win.com") ;
  135.       StartData.PgmName = buff1 ;
  136.       StartData.PgmInputs = buff2 ;
  137.       StartData.SessionType = PROG_DEFAULT ;
  138.       break;
  139.    }
  140.  
  141. /*
  142.  * Get the current drive and directory
  143.  * so that the program can switch to the
  144.  * requested drive and directory before
  145.  * starting the application then return
  146.  * the the original one.
  147.  */
  148. action = CCHMAXPATH ;
  149. DosQueryCurrentDisk(&drvnum, &drvmap) ;
  150. DosQueryCurrentDir(drvnum, homedir, &action) ;
  151.  
  152. if(dir[1] == ':')  /*Move to the drive & directory requested by the user*/
  153.    {
  154.    SetDrive = TRUE ;
  155.    Drive[0] = dir[0] ;
  156.    Drive[1] = 0 ;
  157.    DosSetDefaultDisk(toupper(Drive[0]) - 64) ;
  158.    if(strlen(dir) > 2)
  159.        DosSetCurrentDir(&dir[2]) ;
  160.    }
  161. else if (strlen(dir) > 0)
  162.    DosSetCurrentDir(dir) ;
  163.  
  164. aprc = DosStartSession(&StartData, &SessionID, &pid) ;
  165.  
  166. /*
  167.  * Get the switch handle using the process id.  Then
  168.  * set it active to move it to the foreground.
  169.  */
  170. if( activate && (aprc == 0 || aprc == ERROR_SMG_START_IN_BACKGROUND) )
  171.    {
  172.    while( (hswitch = WinQuerySwitchHandle(NULLHANDLE, pid) ) == NULLHANDLE )
  173.       DosSleep(300L) ;
  174.    WinSwitchToProgram( hswitch ) ;
  175.    }
  176.  
  177. /*
  178.  * free the allocated buffer
  179.  */
  180. if( type == 5 || type == 6 )
  181.    free(buff2) ;
  182.  
  183. /*
  184.  * reset the active drive and directory
  185.  */
  186. DosSetDefaultDisk(drvnum) ;
  187. DosSetCurrentDir(homedir) ;
  188.  
  189. /*
  190.  * Post an error if the program didn't start.
  191.  * ERROR_SMG_START_IN_BACKGROUND is only informational
  192.  * that the parent was not in the foreground so the new
  193.  * app could not be started in the foreground.  The
  194.  * app is still started.
  195.  */
  196. if( aprc != 0 && aprc != ERROR_SMG_START_IN_BACKGROUND )
  197.    {
  198.    sprintf(buff1, "Program failed error 0x%04x", aprc) ;
  199.    WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, buff1, "", 0L, MB_ICONHAND|MB_ENTER) ;
  200.    return 0 ;
  201.    }
  202.  
  203.  
  204. return SessionID ;
  205. }
  206.  
  207.  
  208.  
  209. ULONG StartAppWin(CHAR *app, CHAR *parm, CHAR *dir, CHAR *env, SHORT type, BOOL activate, HWND hwndNotify)
  210. {
  211. CHAR  buff1[CCHMAXPATH], finalenv[600], *ptrenv = finalenv, *tokptr ;
  212. ULONG len, action ;
  213. PROGDETAILS pDetails ;
  214. HAPP  happ ;
  215. HSWITCH hswitch ;
  216. ERRORID err ;
  217. USHORT  errid ;
  218.  
  219. /*
  220.  * Point the structure elements to the appropriate
  221.  * buffers.
  222.  */
  223. memset(&pDetails, 0, sizeof(PROGDETAILS)) ;
  224. pDetails.Length = sizeof(pDetails); /* Length of pDetails structure */
  225. pDetails.pszExecutable = app ;      /* program name */
  226. pDetails.pszStartupDir = dir ;      /* default directory for new app. */
  227. pDetails.pszParameters = parm ;     /* command line */
  228. pDetails.progt.fbVisible = SHE_VISIBLE ;
  229.  
  230.  
  231. /*
  232.  * Pass environment variables in CSV format.  If not null
  233.  * parse out the individual variables and build the
  234.  * environment string.  It is formatted with each environment=value
  235.  * statement separated by a NULL character.  The final variable is
  236.  * followed by two NULL characters.
  237.  *
  238.  * i.e. PATH=C:\\;'\0'LIB=C:\\;'\0''\0'
  239.  *
  240.  */
  241. if(env != NULL && *env != 0)
  242.    {
  243.    memset( finalenv, 0, sizeof(finalenv)) ;
  244.    pDetails.pszEnvironment = finalenv ;
  245.    if( ( tokptr = CsvTok( env )) != NULL) /* CsvTok is a CSV format tokenizer */
  246.       {
  247.       do
  248.          {
  249.          strcpy( ptrenv, tokptr ) ;
  250.          ptrenv += strlen(tokptr) + 1;
  251.          tokptr = CsvTok( NULL ) ;
  252.          }while ( tokptr != NULL ) ;
  253.       }
  254.  
  255.    }
  256.  
  257. /*
  258.  * Convert type to appropriate PM type.
  259.  */
  260. switch(type)
  261.    {
  262.    case 0:
  263.       pDetails.progt.progc = PROG_PM ;
  264.       break;
  265.    case 1:
  266.       pDetails.progt.progc = PROG_WINDOWABLEVIO ;
  267.       break;
  268.    case 2:
  269.       pDetails.progt.progc = PROG_FULLSCREEN ;
  270.       break;
  271.    case 3:
  272.       pDetails.progt.progc = PROG_WINDOWEDVDM ;
  273.       break;
  274.    case 4:
  275.       pDetails.progt.progc = PROG_VDM ;
  276.       break;
  277.    /*
  278.     * NOTE: Windows sessions only work correctly
  279.     * if you use SAF_INSTALLEDCMDLINE.  If you
  280.     * do not specify this flag you must start
  281.     * WINOS2.COM or WIN.COM and pass the program
  282.     * name for fullscreen or seperate seamless
  283.     * sessions.  For common seamless sessions without
  284.     * this flag you must start WINOS2.COM or WIN.COM
  285.     * for the first windows session to be activated
  286.     * then start just the desired program for any
  287.     * additional sessions while a windows session is
  288.     * active.
  289.     */
  290.    case 5:
  291.       pDetails.progt.progc = PROG_31_ENHSEAMLESSCOMMON ;
  292.       break;
  293.    case 6:
  294.       pDetails.progt.progc = PROG_31_ENH ;
  295.       break;
  296.    }
  297.  
  298. /*
  299.  * foreground or background
  300.  */
  301. if( activate )
  302.    pDetails.swpInitial.hwndInsertBehind = HWND_TOP ;
  303. else
  304.    pDetails.swpInitial.hwndInsertBehind = HWND_BOTTOM ;
  305.  
  306. /*
  307.  * Start the application.
  308.  */
  309. happ = WinStartApp( hwndNotify, &pDetails, NULL, NULL, SAF_INSTALLEDCMDLINE|SAF_STARTCHILDAPP) ;
  310.  
  311. /*
  312.  * Get error and post message.
  313.  */
  314. if( happ == NULLHANDLE )
  315.    {
  316.    err = WinGetLastError( WinQueryAnchorBlock( hwndNotify ) ) ;
  317.    errid = ERRORIDERROR(err) ;
  318.    sprintf(buff1, "Program failed error %x", errid) ;
  319.    WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, buff1, "", 0L, MB_ICONHAND|MB_ENTER) ;
  320.    }
  321.  
  322. return happ ;
  323. }
  324.