process.inc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. begin
  119. CreatePipeHandles(SI.hStdInput,HI);
  120. CreatePipeHandles(HO,Si.hStdOutput);
  121. if CE then
  122. CreatePipeHandles(HE,SI.hStdError)
  123. else
  124. begin
  125. SI.hStdError:=SI.hStdOutput;
  126. HE:=HO;
  127. end;
  128. end;
  129. Procedure TProcess.Execute;
  130. Var
  131. PName,PDir,PCommandLine : PChar;
  132. FEnv: pointer;
  133. FCreationFlags : Cardinal;
  134. FProcessAttributes : TSecurityAttributes;
  135. FThreadAttributes : TSecurityAttributes;
  136. FProcessInformation : TProcessInformation;
  137. FStartupInfo : STARTUPINFO;
  138. HI,HO,HE : THandle;
  139. begin
  140. FInheritHandles:=True;
  141. PName:=Nil;
  142. PCommandLine:=Nil;
  143. PDir:=Nil;
  144. If FApplicationName<>'' then
  145. PName:=Pchar(FApplicationName);
  146. If FCommandLine<>'' then
  147. PCommandLine:=Pchar(FCommandLine);
  148. If FCurrentDirectory<>'' then
  149. PDir:=Pchar(FCurrentDirectory);
  150. if FEnvironment.Count<>0 then
  151. FEnv:=StringsToPChars(FEnvironment)
  152. else
  153. FEnv:=Nil;
  154. Try
  155. FCreationFlags:=GetCreationFlags(Self);
  156. InitProcessAttributes(Self,FProcessAttributes);
  157. InitThreadAttributes(Self,FThreadAttributes);
  158. InitStartupInfo(Self,FStartUpInfo);
  159. If poUsePipes in FProcessOptions then
  160. CreatePipes(HI,HO,HE,FStartupInfo,Not(poStdErrToOutPut in FProcessOptions));
  161. Try
  162. If Not CreateProcess (PName,PCommandLine,@FProcessAttributes,@FThreadAttributes,
  163. FInheritHandles,FCreationFlags,FEnv,PDir,FStartupInfo,
  164. fProcessInformation) then
  165. Raise EProcess.CreateFmt('Failed to execute %s : %d',[FCommandLine,GetLastError]);
  166. FProcessHandle:=FProcessInformation.hProcess;
  167. FThreadHandle:=FProcessInformation.hThread;
  168. FProcessID:=FProcessINformation.dwProcessID;
  169. Finally
  170. if POUsePipes in FProcessOptions then
  171. begin
  172. FileClose(FStartupInfo.hStdInput);
  173. FileClose(FStartupInfo.hStdOutput);
  174. if Not (poStdErrToOutPut in FProcessOptions) then
  175. FileClose(FStartupInfo.hStdError);
  176. CreateStreams(HI,HO,HE);
  177. end;
  178. end;
  179. FRunning:=True;
  180. Finally
  181. If FEnv<>Nil then
  182. FreeMem(FEnv);
  183. end;
  184. if not (csDesigning in ComponentState) and // This would hang the IDE !
  185. (poWaitOnExit in FProcessOptions) and
  186. not (poRunSuspended in FProcessOptions) then
  187. WaitOnExit;
  188. end;
  189. Function TProcess.WaitOnExit : Boolean;
  190. Var
  191. R : DWord;
  192. begin
  193. R:=WaitForSingleObject (FProcessHandle,Infinite);
  194. Result:=(R<>Wait_Failed);
  195. If Result then
  196. GetExitStatus;
  197. FRunning:=False;
  198. end;
  199. Function TProcess.Suspend : Longint;
  200. begin
  201. Result:=SuspendThread(ThreadHandle);
  202. end;
  203. Function TProcess.Resume : LongInt;
  204. begin
  205. Result:=ResumeThread(ThreadHandle);
  206. end;
  207. Function TProcess.Terminate(AExitCode : Integer) : Boolean;
  208. begin
  209. Result:=False;
  210. If ExitStatus=Still_active then
  211. Result:=TerminateProcess(Handle,AexitCode);
  212. end;
  213. Procedure TProcess.SetShowWindow (Value : TShowWindowOptions);
  214. begin
  215. FShowWindow:=Value;
  216. end;