source: trunk/Library/Execute.pas@ 25

Last change on this file since 25 was 17, checked in by RBRi, 19 years ago

+ Library

  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1Unit Execute;
2
3Interface
4
5Type
6 Results=record
7 RunResult: integer;
8 ProgramResult: integer;
9 end;
10
11 TermQResults=record
12 SessionID: WORD;
13 ResultCode: WORD;
14 end;
15
16Const
17 COULD_NOT_START=-7;
18 INTERNAL_ERROR=-77;
19
20Var
21 DosStartSessionResult: integer;
22
23Function RunProgram( name:string; parameters: string ):integer;
24
25Function RunCommand( command: string ):integer;
26
27Implementation
28
29Uses
30 BseDos, OS2Def, BseErr, Forms;
31
32Function RunCommand( command: string ):integer;
33Begin
34 Result:=RunProgram( 'cmd.exe', '/c '+command );
35End;
36
37Function RunProgram( name:string; parameters: string ): integer;
38Type
39 pByte=^BYTE;
40Var
41 psd:STARTDATA;
42 SessID:LONGWORD;
43 apid:LONGWORD;
44 PgmTitle:CSTRING;
45 PgmName:CSTRING;
46 ObjBuf:CSTRING;
47 rc:Integer;
48
49 Args, ReportTypeStr:CSTRING;
50
51 TerminationQueue:HQueue;
52 QueueName: CSTRING;
53 QueueRequest: REQUESTDATA;
54 DataLength: ULONG;
55 DataAddress: ^TermQResults;
56 ElementCode: ULONG;
57 NoWait: BOOL;
58 ElemPriority: BYTE;
59 SemName: CString;
60 SemHandle: HEV;
61 OwningPID: PID;
62
63 SemPostCount: ULONG;
64Begin
65 DosStartSessionResult:=0;
66
67 QueueName:='\QUEUES\SIBYL_EXECUTE_TERMQ';
68 rc:= DosCreateQueue( TerminationQueue,
69 QUE_FIFO, // normal queue
70 QueueName );
71 if (rc<>0) then
72 begin
73 Result:=INTERNAL_ERROR;
74 exit;
75 end;
76
77 psd.Length := SizeOf( psd );
78 psd.Related := SSF_RELATED_CHILD; // Yes we want to know about it
79 psd.FgBg := SSF_FGBG_FORE; // run in foreground
80 psd.TraceOpt := SSF_TRACEOPT_NONE; // no tracing!
81
82 PgmName := name; // copy to a cstring
83 psd.PgmName := @PgmName; // program
84 psd.PgmTitle := @PgmName; // window title
85
86 Args:=parameters; // copy to a cstring
87 psd.PgmInputs := @Args; //arguments
88 psd.TermQ := @QueueName; // Termination Queue name
89 psd.Environment := NIL; // no special environment to pass
90 psd.InheritOpt := SSF_INHERTOPT_PARENT;
91 // use parent file handles
92 // AND (more importantly) parent's current drive and dir
93 psd.SessionType := SSF_TYPE_DEFAULT; // whatever the exe says
94 psd.IconFile := NIL; // no icon file
95 psd.PgmHandle := 0; // no program handle
96 psd.PgmControl := 0; // SSF_CONTROL_MINIMIZE; // run minimized
97 psd.InitXPos :=0; // position x
98 psd.InitYPos :=0; // position y
99 psd.Reserved := 0; // blah
100 psd.ObjectBuffer := @ObjBuf; // put errors here
101 psd.ObjectBuffLen := 100; // up to 100 chars
102
103 rc := DosStartSession( psd, SessID, apid );
104
105 if (rc<>0)
106 // but we don't care if it just started in the background!
107 and (rc<>ERROR_SMG_START_IN_BACKGROUND)
108 then
109 begin
110 Result:=COULD_NOT_START;
111 DosStartSessionResult:=rc;
112 DosCloseQueue( TerminationQueue );
113 exit;
114 end;
115
116 // DosCloseQueue( TerminationQueue );
117 // exit;
118
119 // create a semaphore so we can check the queue!!
120 SemName := '\SEM32\SIBYL_EXECUTE_TERMQ';
121 rc := DosCreateEventSem( SemName,
122 SemHandle,
123 0,
124 FALSE );
125 if ( rc <> 0 ) then
126 begin
127 Result:= INTERNAL_ERROR;
128 DosStartSessionResult:= rc;
129 DosCloseQueue( TerminationQueue );
130 exit;
131 end;
132
133 ElementCode:=0; // get element at front of queue
134 NoWait:=True; // don't wait for data: so we supply semaphore instead
135
136 // assocaite the semaphore with the queue, don't remove item if it's already there
137 rc:= DosPeekQueue( TerminationQueue,
138 QueueRequest,
139 DataLength,
140 DataAddress,
141 ElementCode,
142 NoWait,
143 ElemPriority,
144 SemHandle );
145
146 repeat
147 rc := DosQueryEventSem( SemHandle, SemPostCount );
148
149 // Handle PM messages (including to our own app!)
150 Application.ProcessMessages;
151
152 // Give up CPU briefly so we don't appear too greedy when idle.
153 DosSleep( 1 );
154
155 until SemPostCount > 0; // until semaphore is posted, indicating an item in the TermQ
156
157 // The program has terminated.
158 // Now read the item
159 rc:= DosReadQueue( TerminationQueue,
160 QueueRequest,
161 DataLength,
162 DataAddress,
163 ElementCode,
164 NoWait,
165 ElemPriority,
166 SemHandle );
167
168 Result:=DataAddress^.ResultCode;
169 DosCloseQueue( TerminationQueue );
170 // Free the memory used by the queue element
171 DosFreeMem( DataAddress );
172
173 // Close semaphore
174 rc := DosCloseEventSem( SemHandle );
175
176End;
177
178Initialization
179End.
Note: See TracBrowser for help on using the repository browser.