[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

HOW WE STOPE CODE UNTIL THE EXTENAL EXE FINISH

Posted on 2001-06-10
4
Medium Priority
?
393 Views
Last Modified: 2010-04-06
WHEN CALLING EXE TO RUN HOW WE STOPE CODE UNTIL THE EXE FINISH?
I MAKING A PRG. WITH DELPHI TO CALE EN EXTRENAL EXE FILE AND I WANT TO STOE THE CODE RUNING UNTIL THE EXTERNAL EXE FILE FINISH RUNNING. AND THEN THE CODE CONTENUE RENNING.
IF WE CAN USE API. FUNCTION TELL ME.
THENKS
AHMED RAGAB
0
Comment
Question by:RAGAB2000
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 5

Expert Comment

by:alanwhincup
ID: 6173594
You could do it like this:

Make sure you add ShellAPI to the uses clause of the unit.

procedure TForm1.Button1Click(Sender: TObject);
var
  ExInfo : TShellExecuteInfo;
  ExitCode : DWORD;
begin
  FillChar(ExInfo, SizeOf(ExInfo), 0);
  with ExInfo do
  begin
    cbSize := SizeOf(ExInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    Wnd := Handle;
    lpVerb := 'Open';
    lpFile := Pchar('notepad');
    nShow := SW_SHOWNORMAL
  end;
  if ShellExecuteEx(@ExInfo) then
  begin
    while GetExitCodeProcess(ExInfo.hProcess, ExitCode) and
          (ExitCode = STILL_ACTIVE) do
      Application.ProcessMessages;
    CloseHandle(ExInfo.hProcess);
  end
  else
    ShowMessage(SysErrorMessage(GetLastError));
  ShowMessage('Program Ended.');
end;

Cheers,

Alan
0
 
LVL 17

Accepted Solution

by:
inthe earned 200 total points
ID: 6173596
hi,
(caps-lock stuck on? ;-)


two methods:

var
Form1: TForm1;
ProcessHandle: Thandle = 0;

implementation

{$R *.DFM}

uses shellapi;

procedure TForm1.Button1Click(Sender: TObject);
Var
exInfo: TShellExecuteInfo;
Begin
FillChar( exInfo, Sizeof(exInfo), 0 );
With exInfo Do Begin
cbSize:= Sizeof( exInfo );
fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
Wnd := GetActiveWindow();
ExInfo.lpVerb := 'open';
lpFile:= 'D:\hello.rtf'; //your exe here
nShow := SW_SHOWNORMAL;
End;
If ShellExecuteEx( @exInfo ) Then Begin
ProcessHandle := exInfo.HProcess;
End
Else
ShowMessage(SysErrorMessage( GetLastError ));
while WaitForSingleObject(ExInfo.hProcess, 50) <> WAIT_OBJECT_0 do
 Application.ProcessMessages;
CloseHandle(ProcessHandle);
showmessage('process finished');
end;








or:

runthread example using notepad:


unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
  ExtCtrls, ComCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const unitName = 'runThread_.';

type TRunThread = class(TThread)
  private
    processHandle : cardinal;
    processReady  : boolean;
    waitingThread : cardinal;
    procedure Execute; override;
  end;

procedure TRunThread.Execute;
begin
  WaitForSingleObject(processHandle,INFINITE);
  processReady:=true;
  PostThreadMessage(waitingThread,WM_NULL,0,0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var si  : TStartupInfo;
    pi  : TProcessInformation;
    dw1 : dword;
begin
  enabled:=false;
  caption:='start copy...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  si.dwFlags:=STARTF_USESHOWWINDOW; si.wShowWindow:=SW_NORMAL;
  if CreateProcess(nil,'c:\windows\notepad.exe',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='copy started...';
    with TRunThread.Create(true) do
      try
        processHandle:=pi.hProcess;
        processReady:=false;
        waitingThread:=GetCurrentThreadID;
        caption:='wait for copy...';
        Resume;
        repeat
          Application.HandleMessage;
        until Application.Terminated or processReady;
        caption:='notepad closed...';
      finally Free end;
    GetExitCodeProcess(pi.hProcess,dw1);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    caption:='ready... (exitCode='+IntToStr(dw1)+')';
  end else caption:='could not start notepad...';
  enabled:=true;
end;

end.



Regards Barry
0
 
LVL 5

Expert Comment

by:alanwhincup
ID: 6173601
You could also do it by using the CreateProcess function if you dont want to add ShellAPI to the uses clause of the unit:

function ExecFileAndWait(const aCmdLine: string; Hidden, doWait: Boolean): Boolean;
var
  StartupInfo : TStartupInfo;
  ProcessInfo : TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  with StartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    if Hidden then
      wShowWindow := SW_HIDE
    else
      wShowWindow := SW_SHOWNORMAL;
  end;
  Result := CreateProcess(nil, PChar(aCmdLine), nil, nil, False,
                          NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo,
                          ProcessInfo);
  if doWait then
  begin
    if Result then
    begin
      WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecFileAndWait('notepad.exe', False, True);
  ShowMessage('Program Ended.');
end;
0
 

Author Comment

by:RAGAB2000
ID: 6178650
thanks to u all.
Ahmed Ragab
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question