Hi. I have a console application written in .net 4.0 that creates a temporary text file. There's no other interaction between my Delphi7 and the .net application, other than being able to read the file from the Delphi app that the .net app outputs when done. Since I'm not sharing any memory space with the .net application, I thought I could run it like any Delphi app, by creating a process thread, and without any COM or managed/unmanaged junk.
I have something like this in code, but it's not working and I haven't a clue why. What I want is to spawn the application and wait till it is finished writing out the textfile. I don't need to see the console app because there is no user feedback from it. So I'm passing in the application I want to run, and the SW_Hide windows constant to indicate I don't want to see an output screen. BTW, I am running this in WinXP. The cmdpassed would have a different path if I were using Win7, and I'm using this
path as an example. The application does exist in the location I'm using. The .net application could take a couple seconds because it will, ultimately be doing something else besides simply creating my text file. So that is why I'm not doing it asynchronously.
Var
cmdpassed:= 'program files\myapplication folder\ftcloudsession.exe'
Utils.ProcessExecute(CmdPassed, SW_HIDE);
//=========================================================================
//====================== Win32 Extended API Routines ======================
//=========================================================================
function ProcessExecute(CommandLine: String; cShow: Word): Integer;
var
Rslt: LongBool;
StartupInfo: TStartUpInfo;
ProcessInfo: TProcessInformation;
PEC : DWord;
Saved_Cursor: TCursor;
begin
Saved_Cursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
try
FillChar(StartupInfo, SizeOf(TStartupInfo),0);
with StartupInfo do begin
cb := SizeOf(TStartupInfo);
dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
wShowWindow := cShow;
end;
Rslt := CreateProcess(nil,PChar(CommandLine),nil,nil,False,
NORMAL_PRIORITY_CLASS or DETACHED_PROCESS,nil, nil,
StartupInfo, ProcessInfo);
if Rslt then
with ProcessInfo do begin
CloseHandle(hThread);
WaitForInputIdle(hProcess, INFINITE);
repeat
Application.ProcessMessages;
GetExitCodeProcess(hProcess, PEC);
until (PEC <> STILL_ACTIVE) or Application.Terminated;
CloseHandle(hProcess);
Result := 0;
end
else
Result := GetLastError;
finally { wrap up }
Screen.Cursor := Saved_Cursor;
end; { try/finally }
end;
Thanks!
Vote for best question.
Score: 0
# Vote: 0
Date Posted: 16-Sep-2014, at 8:01 AM EST
From: Debbie Erickson
Re: How do I create a process (ie run) a .net application?
Debbie wrote:
> I have something like this in code, but it's not working and I haven't
> a clue why.
What is the actual problem you are having with it? Is an API function failing?
If so, what error code is it reporting? You need to be more specific.
> So I'm passing in the application I want to run, and the SW_Hide windows
> constant to indicate I don't want to see an output screen.
Just because you specify it does not guarantee the app will honor it. It
is more of a hint, not a requirement.
Try something more like this instead:
{code}
Var
// don't forget the drive letter!
cmdpassed := 'c:\program files\myapplication folder\ftcloudsession.exe'
{code}
{code}
function ProcessExecute(CommandLine: String; cShow: Word): Integer;
var
Rslt: DWORD;
StartupInfo: TStartUpInfo;
ProcessInfo: TProcessInformation;
Saved_Cursor: TCursor;
begin
Result := 0;
Saved_Cursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
try
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
StartupInfo.wShowWindow := cShow;
{$IFDEF UNICODE}
UniqueString(CommandLine);
{$ENDIF}
if not CreateProcess(nil, PChar(CommandLine), nil, nil, False, NORMAL_PRIORITY_CLASS
or DETACHED_PROCESS, nil, nil, StartupInfo, ProcessInfo) then begin
Result := GetLastError;
Exit;
end;
try
CloseHandle(ProcessInfo.hThread);
repeat
Rslt := MsgWaitForMultipleObjects(1, ProcessInfo.hProcess, False,
1000, QS_ALLINPUT);
case Rslt of
WAIT_FAILED: begin
Result := GetLastError;
Exit;
end;
WAIT_OBJECT_0+1: Application.ProcessMessages;
end;
until (Rslt = WAIT_OBJECT_0) or Application.Terminated;
finally
CloseHandle(ProcessInfo.hProcess);
end;
finally
Screen.Cursor := Saved_Cursor;
end;
end;
{code}
--
Remy Lebeau (TeamB)