process.pp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$mode objfpc}
  11. {$h+}
  12. unit process;
  13. interface
  14. Uses Classes,
  15. pipes,
  16. SysUtils;
  17. Type
  18. TProcessOption = (poRunSuspended,poWaitOnExit,
  19. poUsePipes,poStderrToOutPut,
  20. poNoConsole,poNewConsole,
  21. poDefaultErrorMode,poNewProcessGroup,
  22. poDebugProcess,poDebugOnlyThisProcess);
  23. TShowWindowOptions = (swoNone,swoHIDE,swoMaximize,swoMinimize,swoRestore,swoShow,
  24. swoShowDefault,swoShowMaximized,swoShowMinimized,
  25. swoshowMinNOActive,swoShowNA,swoShowNoActivate,swoShowNormal);
  26. TStartupOption = (suoUseShowWindow,suoUseSize,suoUsePosition,
  27. suoUseCountChars,suoUseFillAttribute);
  28. TProcessPriority = (ppHigh,ppIdle,ppNormal,ppRealTime);
  29. TProcessOptions = set of TProcessOption;
  30. TStartupOptions = set of TStartupOption;
  31. Type
  32. TProcess = Class (TComponent)
  33. Private
  34. FProcessOptions : TProcessOptions;
  35. FStartupOptions : TStartupOptions;
  36. FProcessID : Integer;
  37. FThreadID : Integer;
  38. FProcessHandle : Thandle;
  39. FThreadHandle : Thandle;
  40. FFillAttribute : Cardinal;
  41. FApplicationName : string;
  42. FConsoleTitle : String;
  43. FCommandLine : String;
  44. FCurrentDirectory : String;
  45. FDesktop : String;
  46. FEnvironment : Tstrings;
  47. FShowWindow : TShowWindowOptions;
  48. FInherithandles : Boolean;
  49. FProcessPriority : TProcessPriority;
  50. dwXCountchars,
  51. dwXSize,
  52. dwYsize,
  53. dwx,
  54. dwYcountChars,
  55. dwy : Cardinal;
  56. Procedure FreeStreams;
  57. Function GetExitStatus : Integer;
  58. Function GetRunning : Boolean;
  59. Function GetWindowRect : TRect;
  60. Procedure SetWindowRect (Value : TRect);
  61. Procedure SetShowWindow (Value : TShowWindowOptions);
  62. Procedure SetWindowColumns (Value : Cardinal);
  63. Procedure SetWindowHeight (Value : Cardinal);
  64. Procedure SetWindowLeft (Value : Cardinal);
  65. Procedure SetWindowRows (Value : Cardinal);
  66. Procedure SetWindowTop (Value : Cardinal);
  67. Procedure SetWindowWidth (Value : Cardinal);
  68. procedure SetApplicationName(const Value: String);
  69. procedure SetProcessOptions(const Value: TProcessOptions);
  70. procedure SetActive(const Value: Boolean);
  71. procedure SetEnvironment(const Value: TStrings);
  72. function PeekExitStatus: Boolean;
  73. Protected
  74. FRunning : Boolean;
  75. FExitCode : Cardinal;
  76. FInputStream : TOutputPipeStream;
  77. FOutputStream : TInputPipeStream;
  78. FStderrStream : TInputPipeStream;
  79. procedure CloseProcessHandles; virtual;
  80. Procedure CreateStreams(InHandle,OutHandle,ErrHandle : Longint);virtual;
  81. procedure FreeStream(var AStream: THandleStream);
  82. Public
  83. Constructor Create (AOwner : TComponent);override;
  84. Destructor Destroy; override;
  85. Procedure Execute; virtual;
  86. procedure CloseInput; virtual;
  87. procedure CloseOutput; virtual;
  88. procedure CloseStderr; virtual;
  89. Function Resume : Integer; virtual;
  90. Function Suspend : Integer; virtual;
  91. Function Terminate (AExitCode : Integer): Boolean; virtual;
  92. Function WaitOnExit : Boolean;
  93. Property WindowRect : Trect Read GetWindowRect Write SetWindowRect;
  94. Property Handle : THandle Read FProcessHandle;
  95. Property ProcessHandle : THandle Read FProcessHandle;
  96. Property ThreadHandle : THandle Read FThreadHandle;
  97. Property ProcessID : Integer Read FProcessID;
  98. Property ThreadID : Integer Read FThreadID;
  99. Property Input : TOutputPipeStream Read FInputStream;
  100. Property Output : TInputPipeStream Read FOutputStream;
  101. Property Stderr : TinputPipeStream Read FStderrStream;
  102. Property ExitStatus : Integer Read GetExitStatus;
  103. Property InheritHandles : Boolean Read FInheritHandles Write FInheritHandles;
  104. Published
  105. Property Active : Boolean Read GetRunning Write SetActive;
  106. Property ApplicationName : String Read FApplicationName Write SetApplicationName;
  107. Property CommandLine : String Read FCommandLine Write FCommandLine;
  108. Property ConsoleTitle : String Read FConsoleTitle Write FConsoleTitle;
  109. Property CurrentDirectory : String Read FCurrentDirectory Write FCurrentDirectory;
  110. Property Desktop : String Read FDesktop Write FDesktop;
  111. Property Environment : TStrings Read FEnvironment Write SetEnvironment;
  112. Property Options : TProcessOptions Read FProcessOptions Write SetProcessOptions;
  113. Property Priority : TProcessPriority Read FProcessPriority Write FProcessPriority;
  114. Property StartupOptions : TStartupOptions Read FStartupOptions Write FStartupOptions;
  115. Property Running : Boolean Read GetRunning;
  116. Property ShowWindow : TShowWindowOptions Read FShowWindow Write SetShowWindow;
  117. Property WindowColumns : Cardinal Read dwXCountChars Write SetWindowColumns;
  118. Property WindowHeight : Cardinal Read dwYSize Write SetWindowHeight;
  119. Property WindowLeft : Cardinal Read dwX Write SetWindowLeft;
  120. Property WindowRows : Cardinal Read dwYCountChars Write SetWindowRows;
  121. Property WindowTop : Cardinal Read dwY Write SetWindowTop ;
  122. Property WindowWidth : Cardinal Read dwXSize Write SetWindowWidth;
  123. Property FillAttribute : Cardinal read FFillAttribute Write FFillAttribute;
  124. end;
  125. EProcess = Class(Exception);
  126. implementation
  127. {$ifdef WINDOWS}
  128. Uses
  129. Windows;
  130. {$endif WINDOWS}
  131. {$ifdef UNIX}
  132. uses
  133. ctypes,
  134. UnixType,
  135. Unix,
  136. Baseunix;
  137. {$endif UNIX}
  138. Resourcestring
  139. SNoCommandLine = 'Cannot execute empty command-line';
  140. SErrNoSuchProgram = 'Executable not found: "%s"';
  141. {$i process.inc}
  142. Constructor TProcess.Create (AOwner : TComponent);
  143. begin
  144. Inherited;
  145. FProcessPriority:=ppNormal;
  146. FShowWindow:=swoNone;
  147. FInheritHandles:=True;
  148. FEnvironment:=TStringList.Create;
  149. end;
  150. Destructor TProcess.Destroy;
  151. begin
  152. FEnvironment.Free;
  153. FreeStreams;
  154. CloseProcessHandles;
  155. Inherited Destroy;
  156. end;
  157. Procedure TProcess.FreeStreams;
  158. begin
  159. If FStderrStream<>FOutputStream then
  160. FreeStream(FStderrStream);
  161. FreeStream(FOutputStream);
  162. FreeStream(FInputStream);
  163. end;
  164. Function TProcess.GetExitStatus : Integer;
  165. begin
  166. If FRunning then
  167. PeekExitStatus;
  168. Result:=FExitCode;
  169. end;
  170. Function TProcess.GetRunning : Boolean;
  171. begin
  172. IF FRunning then
  173. FRunning:=Not PeekExitStatus;
  174. Result:=FRunning;
  175. end;
  176. Procedure TProcess.CreateStreams(InHandle,OutHandle,ErrHandle : Longint);
  177. begin
  178. FreeStreams;
  179. FInputStream:=TOutputPipeStream.Create (InHandle);
  180. FOutputStream:=TInputPipeStream.Create (OutHandle);
  181. if Not (poStderrToOutput in FProcessOptions) then
  182. FStderrStream:=TInputPipeStream.Create(ErrHandle);
  183. end;
  184. procedure TProcess.FreeStream(var AStream: THandleStream);
  185. begin
  186. if AStream = nil then exit;
  187. FileClose(AStream.Handle);
  188. FreeAndNil(AStream);
  189. end;
  190. procedure TProcess.CloseInput;
  191. begin
  192. FreeStream(FInputStream);
  193. end;
  194. procedure TProcess.CloseOutput;
  195. begin
  196. FreeStream(FOutputStream);
  197. end;
  198. procedure TProcess.CloseStderr;
  199. begin
  200. FreeStream(FStderrStream);
  201. end;
  202. Procedure TProcess.SetWindowColumns (Value : Cardinal);
  203. begin
  204. if Value<>0 then
  205. Include(FStartupOptions,suoUseCountChars);
  206. dwXCountChars:=Value;
  207. end;
  208. Procedure TProcess.SetWindowHeight (Value : Cardinal);
  209. begin
  210. if Value<>0 then
  211. include(FStartupOptions,suoUsePosition);
  212. dwYSize:=Value;
  213. end;
  214. Procedure TProcess.SetWindowLeft (Value : Cardinal);
  215. begin
  216. if Value<>0 then
  217. Include(FStartupOptions,suoUseSize);
  218. dwx:=Value;
  219. end;
  220. Procedure TProcess.SetWindowTop (Value : Cardinal);
  221. begin
  222. if Value<>0 then
  223. Include(FStartupOptions,suoUsePosition);
  224. dwy:=Value;
  225. end;
  226. Procedure TProcess.SetWindowWidth (Value : Cardinal);
  227. begin
  228. If (Value<>0) then
  229. Include(FStartupOptions,suoUseSize);
  230. dwXSize:=Value;
  231. end;
  232. Function TProcess.GetWindowRect : TRect;
  233. begin
  234. With Result do
  235. begin
  236. Left:=dwx;
  237. Right:=dwx+dwxSize;
  238. Top:=dwy;
  239. Bottom:=dwy+dwysize;
  240. end;
  241. end;
  242. Procedure TProcess.SetWindowRect (Value : Trect);
  243. begin
  244. Include(FStartupOptions,suoUseSize);
  245. Include(FStartupOptions,suoUsePosition);
  246. With Value do
  247. begin
  248. dwx:=Left;
  249. dwxSize:=Right-Left;
  250. dwy:=Top;
  251. dwySize:=Bottom-top;
  252. end;
  253. end;
  254. Procedure TProcess.SetWindowRows (Value : Cardinal);
  255. begin
  256. if Value<>0 then
  257. Include(FStartupOptions,suoUseCountChars);
  258. dwYCountChars:=Value;
  259. end;
  260. procedure TProcess.SetApplicationName(const Value: String);
  261. begin
  262. FApplicationName := Value;
  263. If (csDesigning in ComponentState) and
  264. (FCommandLine='') then
  265. FCommandLine:=Value;
  266. end;
  267. procedure TProcess.SetProcessOptions(const Value: TProcessOptions);
  268. begin
  269. FProcessOptions := Value;
  270. If poNewConsole in FProcessOptions then
  271. Exclude(FProcessOptions,poNoConsole);
  272. if poRunSuspended in FProcessOptions then
  273. Exclude(FProcessOptions,poWaitOnExit);
  274. end;
  275. procedure TProcess.SetActive(const Value: Boolean);
  276. begin
  277. if (Value<>GetRunning) then
  278. If Value then
  279. Execute
  280. else
  281. Terminate(0);
  282. end;
  283. procedure TProcess.SetEnvironment(const Value: TStrings);
  284. begin
  285. FEnvironment.Assign(Value);
  286. end;
  287. end.