process.inc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. {
  2. Win32 Process .inc.
  3. }
  4. uses Windows;
  5. Const
  6. PriorityConstants : Array [TProcessPriority] of Cardinal =
  7. (HIGH_PRIORITY_CLASS,IDLE_PRIORITY_CLASS,
  8. NORMAL_PRIORITY_CLASS,REALTIME_PRIORITY_CLASS);
  9. procedure TProcess.CloseProcessHandles;
  10. begin
  11. if (FProcessHandle<>0) then
  12. CloseHandle(FProcessHandle);
  13. if (FThreadHandle<>0) then
  14. CloseHandle(FThreadHandle);
  15. end;
  16. Function TProcess.PeekExitStatus : Boolean;
  17. begin
  18. GetExitCodeProcess(ProcessHandle,FExitCode);
  19. Result:=(FExitCode<>Still_Active);
  20. end;
  21. Function GetStartupFlags (P : TProcess): Cardinal;
  22. begin
  23. With P do
  24. begin
  25. Result:=0;
  26. if poUsePipes in FProcessOptions then
  27. Result:=Result or Startf_UseStdHandles;
  28. if suoUseShowWindow in FStartupOptions then
  29. Result:=Result or startf_USESHOWWINDOW;
  30. if suoUSESIZE in FStartupOptions then
  31. Result:=Result or startf_usesize;
  32. if suoUsePosition in FStartupOptions then
  33. Result:=Result or startf_USEPOSITION;
  34. if suoUSECOUNTCHARS in FStartupoptions then
  35. Result:=Result or startf_usecountchars;
  36. if suoUsefIllAttribute in FStartupOptions then
  37. Result:=Result or startf_USEFILLATTRIBUTE;
  38. end;
  39. end;
  40. Function GetCreationFlags(P : TProcess) : Cardinal;
  41. begin
  42. With P do
  43. begin
  44. Result:=0;
  45. if poNoConsole in FProcessOptions then
  46. Result:=Result or Detached_Process;
  47. if poNewConsole in FProcessOptions then
  48. Result:=Result or Create_new_console;
  49. if poNewProcessGroup in FProcessOptions then
  50. Result:=Result or CREATE_NEW_PROCESS_GROUP;
  51. If poRunSuspended in FProcessOptions Then
  52. Result:=Result or Create_Suspended;
  53. if poDebugProcess in FProcessOptions Then
  54. Result:=Result or DEBUG_PROCESS;
  55. if poDebugOnlyThisProcess in FProcessOptions Then
  56. Result:=Result or DEBUG_ONLY_THIS_PROCESS;
  57. if poDefaultErrorMode in FProcessOptions Then
  58. Result:=Result or CREATE_DEFAULT_ERROR_MODE;
  59. result:=result or PriorityConstants[FProcessPriority];
  60. end;
  61. end;
  62. Function StringsToPChars(List : TStrings): pointer;
  63. var
  64. EnvBlock: string;
  65. I: Integer;
  66. begin
  67. EnvBlock := '';
  68. For I:=0 to List.Count-1 do
  69. EnvBlock := EnvBlock + List[i] + #0;
  70. EnvBlock := EnvBlock + #0;
  71. GetMem(Result, Length(EnvBlock));
  72. CopyMemory(Result, @EnvBlock[1], Length(EnvBlock));
  73. end;
  74. Procedure InitProcessAttributes(P : TProcess; Var PA : TSecurityAttributes);
  75. begin
  76. FillChar(PA,SizeOf(PA),0);
  77. PA.nLength := SizeOf(PA);
  78. end;
  79. Procedure InitThreadAttributes(P : TProcess; Var TA : TSecurityAttributes);
  80. begin
  81. FillChar(TA,SizeOf(TA),0);
  82. TA.nLength := SizeOf(TA);
  83. end;
  84. Procedure InitStartupInfo(P : TProcess; Var SI : STARTUPINFO);
  85. Const
  86. SWC : Array [TShowWindowOptions] of Cardinal =
  87. (0,SW_HIDE,SW_Maximize,SW_Minimize,SW_Restore,SW_Show,
  88. SW_ShowDefault,SW_ShowMaximized,SW_ShowMinimized,
  89. SW_showMinNOActive,SW_ShowNA,SW_ShowNoActivate,SW_ShowNormal);
  90. begin
  91. FillChar(SI,SizeOf(SI),0);
  92. With SI do
  93. begin
  94. dwFlags:=GetStartupFlags(P);
  95. if P.FShowWindow<>swoNone then
  96. dwFlags:=dwFlags or Startf_UseShowWindow
  97. else
  98. dwFlags:=dwFlags and not Startf_UseShowWindow;
  99. wShowWindow:=SWC[P.FShowWindow];
  100. if (poUsePipes in P.Options) then
  101. begin
  102. dwFlags:=dwFlags or Startf_UseStdHandles;
  103. end;
  104. if P.FillAttribute<>0 then
  105. begin
  106. dwFlags:=dwFlags or Startf_UseFillAttribute;
  107. dwFillAttribute:=P.FillAttribute;
  108. end;
  109. dwXCountChars:=P.WindowColumns;
  110. dwYCountChars:=P.WindowRows;
  111. dwYsize:=P.WindowHeight;
  112. dwXsize:=P.WindowWidth;
  113. dwy:=P.WindowTop;
  114. dwX:=P.WindowLeft;
  115. end;
  116. end;
  117. Procedure CreatePipes(Var HI,HO,HE : Thandle; Var SI : TStartupInfo; CE : Boolean);
  118. Procedure DoCreatePipeHandles(Var H1,H2 : THandle);
  119. Var
  120. I,O : Longint;
  121. begin
  122. CreatePipeHandles(I,O);
  123. H1:=Thandle(I);
  124. H2:=THandle(O);
  125. end;
  126. begin
  127. DoCreatePipeHandles(SI.hStdInput,HI);
  128. DoCreatePipeHandles(HO,Si.hStdOutput);
  129. if CE then
  130. DoCreatePipeHandles(HE,SI.hStdError)
  131. else
  132. begin
  133. SI.hStdError:=SI.hStdOutput;
  134. HE:=HO;
  135. end;
  136. end;
  137. Procedure TProcess.Execute;
  138. Var
  139. PName,PDir,PCommandLine : PChar;
  140. FEnv: pointer;
  141. FCreationFlags : Cardinal;
  142. FProcessAttributes : TSecurityAttributes;
  143. FThreadAttributes : TSecurityAttributes;
  144. FProcessInformation : TProcessInformation;
  145. FStartupInfo : STARTUPINFO;
  146. HI,HO,HE : THandle;
  147. begin
  148. FInheritHandles:=True;
  149. PName:=Nil;
  150. PCommandLine:=Nil;
  151. PDir:=Nil;
  152. If FApplicationName<>'' then
  153. PName:=Pchar(FApplicationName);
  154. If FCommandLine<>'' then
  155. PCommandLine:=Pchar(FCommandLine);
  156. If FCurrentDirectory<>'' then
  157. PDir:=Pchar(FCurrentDirectory);
  158. if FEnvironment.Count<>0 then
  159. FEnv:=StringsToPChars(FEnvironment)
  160. else
  161. FEnv:=Nil;
  162. Try
  163. FCreationFlags:=GetCreationFlags(Self);
  164. InitProcessAttributes(Self,FProcessAttributes);
  165. InitThreadAttributes(Self,FThreadAttributes);
  166. InitStartupInfo(Self,FStartUpInfo);
  167. If poUsePipes in FProcessOptions then
  168. CreatePipes(HI,HO,HE,FStartupInfo,Not(poStdErrToOutPut in FProcessOptions));
  169. Try
  170. If Not CreateProcess (PName,PCommandLine,@FProcessAttributes,@FThreadAttributes,
  171. FInheritHandles,FCreationFlags,FEnv,PDir,FStartupInfo,
  172. fProcessInformation) then
  173. Raise Exception.CreateFmt('Failed to execute %s : %d',[FCommandLine,GetLastError]);
  174. FProcessHandle:=FProcessInformation.hProcess;
  175. FThreadHandle:=FProcessInformation.hThread;
  176. FProcessID:=FProcessINformation.dwProcessID;
  177. Finally
  178. if POUsePipes in FProcessOptions then
  179. begin
  180. FileClose(FStartupInfo.hStdInput);
  181. FileClose(FStartupInfo.hStdOutput);
  182. if Not (poStdErrToOutPut in FProcessOptions) then
  183. FileClose(FStartupInfo.hStdError);
  184. CreateStreams(HI,HO,HE);
  185. end;
  186. end;
  187. FRunning:=True;
  188. Finally
  189. If FEnv<>Nil then
  190. FreeMem(FEnv);
  191. end;
  192. if not (csDesigning in ComponentState) and // This would hang the IDE !
  193. (poWaitOnExit in FProcessOptions) and
  194. not (poRunSuspended in FProcessOptions) then
  195. WaitOnExit;
  196. end;
  197. Function TProcess.WaitOnExit : Dword;
  198. begin
  199. Result:=WaitForSingleObject (FProcessHandle,Infinite);
  200. If Result<>Wait_Failed then
  201. GetExitStatus;
  202. FRunning:=False;
  203. end;
  204. Function TProcess.Suspend : Longint;
  205. begin
  206. Result:=SuspendThread(ThreadHandle);
  207. end;
  208. Function TProcess.Resume : LongInt;
  209. begin
  210. Result:=ResumeThread(ThreadHandle);
  211. end;
  212. Function TProcess.Terminate(AExitCode : Integer) : Boolean;
  213. begin
  214. Result:=False;
  215. If ExitStatus=Still_active then
  216. Result:=TerminateProcess(Handle,AexitCode);
  217. end;
  218. Procedure TProcess.SetShowWindow (Value : TShowWindowOptions);
  219. begin
  220. FShowWindow:=Value;
  221. end;