|
@@ -0,0 +1,267 @@
|
|
|
|
+{
|
|
|
|
+ Wince Process .inc.
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+uses Windows;
|
|
|
|
+
|
|
|
|
+Const
|
|
|
|
+ PriorityConstants : Array [TProcessPriority] of Cardinal =
|
|
|
|
+ (HIGH_PRIORITY_CLASS,IDLE_PRIORITY_CLASS,
|
|
|
|
+ NORMAL_PRIORITY_CLASS,REALTIME_PRIORITY_CLASS);
|
|
|
|
+
|
|
|
|
+procedure TProcess.CloseProcessHandles;
|
|
|
|
+begin
|
|
|
|
+ if (FProcessHandle<>0) then
|
|
|
|
+ CloseHandle(FProcessHandle);
|
|
|
|
+ if (FThreadHandle<>0) then
|
|
|
|
+ CloseHandle(FThreadHandle);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function TProcess.PeekExitStatus : Boolean;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ GetExitCodeProcess(ProcessHandle,FExitCode);
|
|
|
|
+ Result:=(FExitCode<>Still_Active);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function GetStartupFlags (P : TProcess): Cardinal;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ With P do
|
|
|
|
+ begin
|
|
|
|
+ Result:=0;
|
|
|
|
+ if poUsePipes in FProcessOptions then
|
|
|
|
+ Result:=Result or Startf_UseStdHandles;
|
|
|
|
+ if suoUseShowWindow in FStartupOptions then
|
|
|
|
+ Result:=Result or startf_USESHOWWINDOW;
|
|
|
|
+ if suoUSESIZE in FStartupOptions then
|
|
|
|
+ Result:=Result or startf_usesize;
|
|
|
|
+ if suoUsePosition in FStartupOptions then
|
|
|
|
+ Result:=Result or startf_USEPOSITION;
|
|
|
|
+ if suoUSECOUNTCHARS in FStartupoptions then
|
|
|
|
+ Result:=Result or startf_usecountchars;
|
|
|
|
+ if suoUsefIllAttribute in FStartupOptions then
|
|
|
|
+ Result:=Result or startf_USEFILLATTRIBUTE;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function GetCreationFlags(P : TProcess) : Cardinal;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ With P do
|
|
|
|
+ begin
|
|
|
|
+ Result:=0;
|
|
|
|
+ if poNoConsole in FProcessOptions then
|
|
|
|
+ Result:=Result or Detached_Process;
|
|
|
|
+ if poNewConsole in FProcessOptions then
|
|
|
|
+ Result:=Result or Create_new_console;
|
|
|
|
+ if poNewProcessGroup in FProcessOptions then
|
|
|
|
+ Result:=Result or CREATE_NEW_PROCESS_GROUP;
|
|
|
|
+ If poRunSuspended in FProcessOptions Then
|
|
|
|
+ Result:=Result or Create_Suspended;
|
|
|
|
+ if poDebugProcess in FProcessOptions Then
|
|
|
|
+ Result:=Result or DEBUG_PROCESS;
|
|
|
|
+ if poDebugOnlyThisProcess in FProcessOptions Then
|
|
|
|
+ Result:=Result or DEBUG_ONLY_THIS_PROCESS;
|
|
|
|
+ if poDefaultErrorMode in FProcessOptions Then
|
|
|
|
+ Result:=Result or CREATE_DEFAULT_ERROR_MODE;
|
|
|
|
+ result:=result or PriorityConstants[FProcessPriority];
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function StringsToPWidechars(List : TStrings): pointer;
|
|
|
|
+
|
|
|
|
+var
|
|
|
|
+ EnvBlock: Widestring;
|
|
|
|
+ I: Integer;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ EnvBlock := '';
|
|
|
|
+ For I:=0 to List.Count-1 do
|
|
|
|
+ EnvBlock := EnvBlock + List[i] + #0;
|
|
|
|
+ EnvBlock := EnvBlock + #0;
|
|
|
|
+ GetMem(Result, Length(EnvBlock));
|
|
|
|
+ CopyMemory(Result, @EnvBlock[1], Length(EnvBlock));
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Procedure InitProcessAttributes(P : TProcess; Var PA : TSecurityAttributes);
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ FillChar(PA,SizeOf(PA),0);
|
|
|
|
+ PA.nLength := SizeOf(PA);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Procedure InitThreadAttributes(P : TProcess; Var TA : TSecurityAttributes);
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ FillChar(TA,SizeOf(TA),0);
|
|
|
|
+ TA.nLength := SizeOf(TA);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Procedure InitStartupInfo(P : TProcess; Var SI : STARTUPINFO);
|
|
|
|
+
|
|
|
|
+Const
|
|
|
|
+ SWC : Array [TShowWindowOptions] of Cardinal =
|
|
|
|
+ (0,SW_HIDE,SW_Maximize,SW_Minimize,SW_Restore,SW_Show,
|
|
|
|
+ SW_ShowDefault,SW_ShowMaximized,SW_ShowMinimized,
|
|
|
|
+ SW_showMinNOActive,SW_ShowNA,SW_ShowNoActivate,SW_ShowNormal);
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ FillChar(SI,SizeOf(SI),0);
|
|
|
|
+ With SI do
|
|
|
|
+ begin
|
|
|
|
+ dwFlags:=GetStartupFlags(P);
|
|
|
|
+ if P.FShowWindow<>swoNone then
|
|
|
|
+ dwFlags:=dwFlags or Startf_UseShowWindow
|
|
|
|
+ else
|
|
|
|
+ dwFlags:=dwFlags and not Startf_UseShowWindow;
|
|
|
|
+ wShowWindow:=SWC[P.FShowWindow];
|
|
|
|
+ if (poUsePipes in P.Options) then
|
|
|
|
+ begin
|
|
|
|
+ dwFlags:=dwFlags or Startf_UseStdHandles;
|
|
|
|
+ end;
|
|
|
|
+ if P.FillAttribute<>0 then
|
|
|
|
+ begin
|
|
|
|
+ dwFlags:=dwFlags or Startf_UseFillAttribute;
|
|
|
|
+ dwFillAttribute:=P.FillAttribute;
|
|
|
|
+ end;
|
|
|
|
+ dwXCountChars:=P.WindowColumns;
|
|
|
|
+ dwYCountChars:=P.WindowRows;
|
|
|
|
+ dwYsize:=P.WindowHeight;
|
|
|
|
+ dwXsize:=P.WindowWidth;
|
|
|
|
+ dwy:=P.WindowTop;
|
|
|
|
+ dwX:=P.WindowLeft;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Procedure CreatePipes(Var HI,HO,HE : Thandle; Var SI : TStartupInfo; CE : Boolean);
|
|
|
|
+
|
|
|
|
+ Procedure DoCreatePipeHandles(Var H1,H2 : THandle);
|
|
|
|
+
|
|
|
|
+ Var
|
|
|
|
+ I,O : Longint;
|
|
|
|
+
|
|
|
|
+ begin
|
|
|
|
+ CreatePipeHandles(I,O);
|
|
|
|
+ H1:=Thandle(I);
|
|
|
|
+ H2:=THandle(O);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ DoCreatePipeHandles(SI.hStdInput,HI);
|
|
|
|
+ DoCreatePipeHandles(HO,Si.hStdOutput);
|
|
|
|
+ if CE then
|
|
|
|
+ DoCreatePipeHandles(HE,SI.hStdError)
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ SI.hStdError:=SI.hStdOutput;
|
|
|
|
+ HE:=HO;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Procedure TProcess.Execute;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ PName,PDir,PCommandLine : PWidechar;
|
|
|
|
+ FEnv: pointer;
|
|
|
|
+ FCreationFlags : Cardinal;
|
|
|
|
+ FProcessAttributes : TSecurityAttributes;
|
|
|
|
+ FThreadAttributes : TSecurityAttributes;
|
|
|
|
+ FProcessInformation : TProcessInformation;
|
|
|
|
+ FStartupInfo : STARTUPINFO;
|
|
|
|
+ HI,HO,HE : THandle;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ FInheritHandles:=True;
|
|
|
|
+ PName:=Nil;
|
|
|
|
+ PCommandLine:=Nil;
|
|
|
|
+ PDir:=Nil;
|
|
|
|
+ If FApplicationName<>'' then
|
|
|
|
+ PName:=PWidechar(FApplicationName);
|
|
|
|
+ If FCommandLine<>'' then
|
|
|
|
+ PCommandLine:=PWidechar(FCommandLine);
|
|
|
|
+ If FCurrentDirectory<>'' then
|
|
|
|
+ PDir:=PWidechar(FCurrentDirectory);
|
|
|
|
+ if FEnvironment.Count<>0 then
|
|
|
|
+ FEnv:=StringsToPWideChars(FEnvironment)
|
|
|
|
+ else
|
|
|
|
+ FEnv:=Nil;
|
|
|
|
+ Try
|
|
|
|
+ FCreationFlags:=GetCreationFlags(Self);
|
|
|
|
+ InitProcessAttributes(Self,FProcessAttributes);
|
|
|
|
+ InitThreadAttributes(Self,FThreadAttributes);
|
|
|
|
+ InitStartupInfo(Self,FStartUpInfo);
|
|
|
|
+ If poUsePipes in FProcessOptions then
|
|
|
|
+ CreatePipes(HI,HO,HE,FStartupInfo,Not(poStdErrToOutPut in FProcessOptions));
|
|
|
|
+ Try
|
|
|
|
+ If Not CreateProcess (PName,PCommandLine,@FProcessAttributes,@FThreadAttributes,
|
|
|
|
+ FInheritHandles,FCreationFlags,FEnv,PDir,@FStartupInfo,
|
|
|
|
+ fProcessInformation) then
|
|
|
|
+ Raise Exception.CreateFmt('Failed to execute %s : %d',[FCommandLine,GetLastError]);
|
|
|
|
+ FProcessHandle:=FProcessInformation.hProcess;
|
|
|
|
+ FThreadHandle:=FProcessInformation.hThread;
|
|
|
|
+ FProcessID:=FProcessINformation.dwProcessID;
|
|
|
|
+ Finally
|
|
|
|
+ if POUsePipes in FProcessOptions then
|
|
|
|
+ begin
|
|
|
|
+ FileClose(FStartupInfo.hStdInput);
|
|
|
|
+ FileClose(FStartupInfo.hStdOutput);
|
|
|
|
+ if Not (poStdErrToOutPut in FProcessOptions) then
|
|
|
|
+ FileClose(FStartupInfo.hStdError);
|
|
|
|
+ CreateStreams(HI,HO,HE);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ FRunning:=True;
|
|
|
|
+ Finally
|
|
|
|
+ If FEnv<>Nil then
|
|
|
|
+ FreeMem(FEnv);
|
|
|
|
+ end;
|
|
|
|
+ if not (csDesigning in ComponentState) and // This would hang the IDE !
|
|
|
|
+ (poWaitOnExit in FProcessOptions) and
|
|
|
|
+ not (poRunSuspended in FProcessOptions) then
|
|
|
|
+ WaitOnExit;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function TProcess.WaitOnExit : Dword;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result:=WaitForSingleObject (FProcessHandle,Infinite);
|
|
|
|
+ If Result<>Wait_Failed then
|
|
|
|
+ GetExitStatus;
|
|
|
|
+ FRunning:=False;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function TProcess.Suspend : Longint;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result:=SuspendThread(ThreadHandle);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function TProcess.Resume : LongInt;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result:=ResumeThread(ThreadHandle);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function TProcess.Terminate(AExitCode : Integer) : Boolean;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result:=False;
|
|
|
|
+ If ExitStatus=Still_active then
|
|
|
|
+ Result:=TerminateProcess(Handle,AexitCode);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Procedure TProcess.SetShowWindow (Value : TShowWindowOptions);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ FShowWindow:=Value;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|