[comp.windows.ms] Calling other .EXEs from Windows Apps

pdavid@polyslo.CalPoly.EDU (Paul C. David) (05/13/89)

A few days ago I asked about how one could execute other
.EXEs from inside of a windows application.  One reply
was to try using spawn.  The problem is that spawn doesn't
seem to like coexisting with Window's memory managers,
thus yields unpredictable results.  It may work, or....
Anyway, its got to be possible, since other applications
seem to make use of the notepad program (like PageMaker
does). Any help at all is appreciated, since I don't look
forward to writing my own editor :-).
			Thanks
				-Paul.
-- 
Paul C. David		pdavid@polyslo.CalPoly.EDU
California Polytechic State University, San Luis Obispo
Unity through inviting learning by doing is our style.

rogerson@PEDEV.Columbia.NCR.COM (Dale Rogerson) (05/18/89)

In article <11349@polyslo.CalPoly.EDU> pdavid@polyslo.CalPoly.EDU (Paul C. David) writes:
>A few days ago I asked about how one could execute other
>.EXEs from inside of a windows application.  One reply
>was to try using spawn.  The problem is that spawn doesn't
>seem to like coexisting with Window's memory managers,
>thus yields unpredictable results.  It may work, or....
>Anyway, its got to be possible, since other applications
>seem to make use of the notepad program (like PageMaker
>does). Any help at all is appreciated, since I don't look
>forward to writing my own editor :-).
>Paul C. David		pdavid@polyslo.CalPoly.EDU

Here is something I pulled off the net back in December.  See if this works
I have not tried it.

-----dale
	rogerson-----
==========================================================================


In article <115@secola.Columbia.NCR.COM> ramspott@secola.Columbia.NCR.COM (John Ramspott) writes:
>
>Has anyone out there tried to get one windows task to spawn another task in
>Windows/286? I would like to startup some homemade "device drivers" from my
>application program. I can't find any Window functions for creating another
>Windows process. I am suspicious of spawning since you can't run a Windows
>app from the DOS command line. In other words, I want a system of programs
>to be initiated when the user starts up the main application window.
  This came from online, and it works for running other windows apps.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	readme.doc
#	s.c
#	spawh.shar
#	spawn
#	spawn.c
#	spawn.def
#	spawn.lnk
#	spawn.rc
#	wspawn.asm
# This archive created: Tue Dec  6 17:54:54 1988
# By:	Charles Anderson (The Midgard Realm, St Paul, MN)
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'readme.doc'
then
	echo shar: "will not over-write existing file 'readme.doc'"
else
cat << \SHAR_EOF > 'readme.doc'
To spawn an application in the windows 2.03 system, it is required
that the spawning app. uses the interupt 21 function 4b DOS call
to perform the spawn and that the spawning app. remain resident in
the system until the spawned application finishes.

This sample provides the assembler code, assembled object file,
and a C include file containing the function prototyping.  The
C source files included will spawn a copy of the calculator and
then fall into a "getmessage loop".  The getmessage loop is removed
from the initialization sources to minimize the amount of memory
needed to keep the spawning application active.
SHAR_EOF
fi
if test -f 's.c'
then
	echo shar: "will not over-write existing file 's.c'"
else
cat << \SHAR_EOF > 's.c'
#include "windows.h"



/* small, resident piece of code.  In windows 2.03, the spawing
 * application must remain resident until the spawned application
 * completes.  This loop is removed from rest of the application 
 * code segment so that the memory wasted could be minimized.
 */
int FAR PASCAL Loop()
{
  MSG   msg;

  while (GetMessage ((LPMSG)&msg, NULL, 0, 0))
    DispatchMessage ((LPMSG)&msg);

  return (int)msg.wParam;
}


SHAR_EOF
fi
if test -f 'spawh.shar'
then
	echo shar: "will not over-write existing file 'spawh.shar'"
else
cat << \SHAR_EOF > 'spawh.shar'

SHAR_EOF
fi
if test -f 'spawn'
then
	echo shar: "will not over-write existing file 'spawn'"
else
cat << \SHAR_EOF > 'spawn'
spawn.obj: spawn.c
  CL -d -c -AS -Gsw -Os -Zped -NT _TEXT spawn.c

s.obj: s.c
  CL -d -c -AS -Gsw -Os -Zped -NT _LOOP s.c

wspawn.obj: wspawn.asm
   masm wspawn;

spawn.exe: spawn.obj s.obj wspawn.obj spawn.rc spawn.def
    link4 @spawn.lnk
    mapsym spawn
    rc spawn.rc


SHAR_EOF
fi
if test -f 'spawn.c'
then
	echo shar: "will not over-write existing file 'spawn.c'"
else
cat << \SHAR_EOF > 'spawn.c'
#include "windows.h"
#include "process.h"

int FAR PASCAL Int21Function4B(BYTE,LPSTR,LPSTR); /* assembler dos interface */
int FAR PASCAL Loop();                            /* resident loop */

typedef struct {
  WORD    environment;
  LPSTR   commandline;
  LPSTR   FCB1;
  LPSTR   FCB2;
} EXECBLOCK;                                /* as defined in MS-DOS PROG. REF */


EXECBLOCK   exec;
WORD        w [2];
HANDLE      hInst;


int CauseSpawn (app)
LPSTR app;
{
  int i;

  GlobalCompact (-1L);                /* free as much memory as possible */
  LockData (0);                       /* lock data segment */

  exec.environment = 0;               /* pass default environment */
  exec.commandline = (LPSTR)"\0\r";   /* command line to spawned application */

/* the command line has the format:
 * byte:   number of chars in command line not to include the return char */
/* char[]: command characters */
/* char:   return character */

/* example: to send an application the file name foo.txt as the command
 * line.
 * exec.commandline = (LPSTR)"\007foo.txt\r";
 * NOTE: the \007 is octal seven, the number of characters in 'foo.txt'
 */

  w[0] = 2;                           /* two byte command show arg. */
  w[1] = SHOW_OPENWINDOW;             /* command show arg. */
  exec.FCB1 = (LPSTR)w;               /* point to the command show */
  exec.FCB2 = (LPSTR)NULL;            /* reserved */

  i = Int21Function4B (0, (LPSTR)app, (LPSTR)&exec);  /* call assembler function */

  UnlockData (0);                                     /* unlock the data segment */
  return (i);
}


int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int     cmdShow;
{
  hInst = hInstance;
  CauseSpawn ((LPSTR)"calc.exe");               /* spawn calculator */
  if (hPrevInstance)
    return (TRUE);                              /* if a previous instance of this
                                                 * sample exists, exit. */
    return (Loop ());                           /* if first instance, remain resident */
}

SHAR_EOF
fi
if test -f 'spawn.def'
then
	echo shar: "will not over-write existing file 'spawn.def'"
else
cat << \SHAR_EOF > 'spawn.def'
NAME    SPAWN

DESCRIPTION 'Simple Microsoft Windows Application'

STUB    'WINSTUB.EXE'

CODE    MOVEABLE DISCARDABLE
DATA    MOVEABLE MULTIPLE

SEGMENTS
  _TEXT MOVEABLE DISCARDABLE
  _LOOP MOVEABLE DISCARDABLE

STACKSIZE 4096
HEAPSIZE 128


SHAR_EOF
fi
if test -f 'spawn.lnk'
then
	echo shar: "will not over-write existing file 'spawn.lnk'"
else
cat << \SHAR_EOF > 'spawn.lnk'
spawn s wspawn
/align:16
spawn/map/li
slibw
spawn.def

SHAR_EOF
fi
if test -f 'spawn.rc'
then
	echo shar: "will not over-write existing file 'spawn.rc'"
else
cat << \SHAR_EOF > 'spawn.rc'
#include "style.h"

SHAR_EOF
fi
if test -f 'wspawn.asm'
then
	echo shar: "will not over-write existing file 'wspawn.asm'"
else
cat << \SHAR_EOF > 'wspawn.asm'
include cmacros.inc

sBegin CODE
assumes CS,CODE

cProc   Int21Function4B,<PUBLIC,FAR>,<bx,cx,dx,si,di,es,ds>
        parmB mode                      ; mode of int 21 func. 4b call
        parmD path                      ; address of exe file name
        parmD execblock                 ; address of exec block
cBegin
        mov al,mode                     ; set register args as per int 21
        lds dx,path                     ; function 4b DOS Programmers Reference
        les bx,execblock
        mov ah,4bh
        int 21h                         ; call  DOS
cEnd

sEnd CODE
END

SHAR_EOF
fi
exit 0
#	End of shell archive
--
Charlie Anderson - caa@midgard.mn.org