Mega Search
23.2 Million


Sign Up

Make a donation  
How do I create a process (ie run) a .net application?  
News Group: embarcadero.public.delphi.nativeapi

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?  
News Group: embarcadero.public.delphi.nativeapi
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)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 16-Sep-2014, at 9:51 AM EST
From: Remy Lebeau (TeamB)