; if InputFile <> '' then
begin
{ create the appropriate handle for the input file }
hInputFile := CreateFile(
pInputFile, { pointer to name of the file }
GENERIC_READ or GENERIC_WRITE, { access (read-write) mode }
FILE_SHARE_READ or FILE_SHARE_WRITE, { share mode }
@SecAtrrs, { pointer to security attributes }
OPEN_ALWAYS, { how to create }
FILE_ATTRIBUTE_NORMAL
or FILE_FLAG_WRITE_THROUGH, { file attributes }
0); { handle to file with attrs to copy }
{ is hInputFile a valid handle? }
if hInputFile = INVALID_HANDLE_VALUE then
raise Exception.CreateFmt(ROUTINE_ID + #10 + #10 +
'WinApi function CreateFile returned an invalid handle value' + #10 +
'for the input file * %s *' + #10 + #10 +
ErrMsg, [InputFile]);
end else
{ we aren't using an input file }
hInputFile := 0;
{ create the appropriate handle for the output file }
hOutputFile := CreateFile(
pOutPutFile, { pointer to name of the file }
GENERIC_READ or GENERIC_WRITE, { access (read-write) mode }
FILE_SHARE_READ or FILE_SHARE_WRITE, { share mode }
@SecAtrrs, { pointer to security attributes }
CREATE_ALWAYS, { how to create }
FILE_ATTRIBUTE_NORMAL
or FILE_FLAG_WRITE_THROUGH, { file attributes }
0 ); { handle to file with attrs to copy }
{ is hOutputFile a valid handle? }
if hOutputFile = INVALID_HANDLE_VALUE then
raise Exception.CreateFmt(ROUTINE_ID + #10 + #10 +
'WinApi function CreateFile returned an invalid handle value' + #10 +
'for the output file * %s *' + #10 + #10 +
ErrMsg, [OutputFile]);
{ prepare StartupInfo structure }
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.hStdOutput := hOutputFile;
StartupInfo.hStdInput := hInputFile;
{ create the app }
Result := CreateProcess(
NIL, { pointer to name of executable module }
pCommandLine, { pointer to command line string }
NIL, { pointer to process security attributes }
NIL, { pointer to thread security attributes }
TRUE, { handle inheritance flag }
HIGH_PRIORITY_CLASS, { creation flags }
NIL, { pointer to new environment block }
NIL, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo); { pointer to PROCESS_INF }
{ wait for the app to finish its job and take the handles to free them later }
if Result then
begin
WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
hAppProcess := ProcessInfo.hProcess;
hAppThread := ProcessInfo.hThread;
end else
raise Exception.Create(ROUTINE_ID + #10 + #10 +
'Function failure' + #10 + #10 + ErrMsg);
finally
{ close the handles
Kernel objects, like the process and the files we created in this case,
are maintained by a usage count.
So, for cleaning up purposes we have to close the handles
to inform the system that we don't need the objects anymore }
if hOutputFile <> 0 then
CloseHandle(hOutputFile);
if hInputFile <> 0 then
CloseHandle(hInputFile);
if hAppThread <> 0 then
CloseHandle(hAppThread);
if hAppProcess <> 0 then
CloseHandle(hAppProcess);
{ restore the old cursor }
Screen.Cursor:= OldCursor;
end;
end; { CreateDOSProcessRedirected }