Link to home
Start Free TrialLog in
Avatar of entercite
entercite

asked on

How to launch a .bat from an application

Hi,

 Does anyone know how I can call a .bat program from delphi the pause for 20 seconds and start another bat program. A Example would be great. I am using Delphi 5 if it matters.

Thanks,

ec
Avatar of cqhall
cqhall

If you want each batch file to finish before starting the 20 second delay, you'll need a special call to wait for the each call to complete. See WinExecAndWait32 below.  If the timer can start immediately after the batch file starts, use WinExec, CreateProcess of ShellExecute.  WinExec is the easiest and sounds adequate for your needs.

procedure TForm1.Button1Click(Sender: TObject);
begin
 {wait for each batch file to complete - WinExecAndWait  defined below}
  WinExecAndWait32('c:\batch1.bat',sw_show);
  update; //refresh form
  sleep(20000);
  WinExecAndWait32('c:\batch2.bat',sw_show);
  update;
  sleep(20000);
  ...
          { OR }
  {timer starts immediately}
  WinExec('c:\batch1.bat',sw_show);
  update; //refresh form
  sleep(20000);
  WinExec('c:\batch2.bat',sw_show);
  update;
  sleep(20000);
  ...
end;


function WinExecAndWait32(FileName:String; Visibility : integer): DWord;

var
 zAppName     : array[0..512] of char;
 zCurDir      : array[0..255] of char;
 WorkDir      : String;
 StartupInfo  : TStartupInfo;
 ProcessInfo  : TProcessInformation;
const
 Win95=1;
 NT40=2;

begin
 StrPCopy(zAppName,FileName);
 GetDir(0,WorkDir);
 StrPCopy(zCurDir,WorkDir);
 FillChar(StartupInfo,Sizeof(StartupInfo),#0);
 StartupInfo.cb := Sizeof(StartupInfo);
 StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
 StartupInfo.wShowWindow := Visibility;
 if not CreateProcess(nil,
  zAppName,                      { pointer to command line string }
  nil,                           { pointer to process security attributes}
  nil,                           { pointer to thread security attributes }
  false,                         { handle inheritance flag }
  CREATE_NEW_CONSOLE or          { creation flags }
  NORMAL_PRIORITY_CLASS,
  nil,                           { pointer to new environment block }
  nil,                           { pointer to current directory name }
  StartupInfo,                   { pointer to STARTUPINFO }
  ProcessInfo) then Result := 0  { pointer to PROCESS_INF }
 else
  begin
   WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
   GetExitCodeProcess(ProcessInfo.hProcess,Result);
  end;
end;

Avatar of Mohammed Nasman
uses
  ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShellExecute(Handle,'Open','c:\MyFile1.bat',nil,nil,SW_ShowNormal);
  Sleep(20000); // wait for 20 second;
  ShellExecute(Handle,'Open','c:\MyFile2.bat',nil,nil,SW_ShowNormal);
end;
20 seconds is a long time... your app may be found as froozen, i'd rather use...


uses ShellAPI;

function BatThread(P: Pointer): LongInt; stdcall;
begin
  Form1.Button1.Enabled := False;
  ShellExecute(Handle, 'Open', 'c:\MyFile1.bat', nil, nil, SW_ShowNormal);
  Sleep(20000);
  ShellExecute(Handle, 'Open', 'c:\MyFile2.bat', nil, nil, SW_ShowNormal);
  Form1.Button1.Enabled := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ThreadID  : DWORD;
  ThHandle  : THandle;
begin
  ThHandle := CreateThread(nil, 0, @BatThread, nil, 0, ThreadID);
  if ThHandle = 0 then MessageBox(Handle, 'Thread create error', PChar(Caption), MB_OK or MB_ICONERROR or MB_APPLMODAL);
end;
Keep it as simple as posible people !

/////////////////////////////////////
WinExec('c:\BatchFile.Bat',sw_show);
Sleep(20000);
WinExec('c:\BatchFile.Bat',sw_show);
Sleep(20000);
/////////////////////////////////////

Thanks
Alex Rakia

For questions please contact me at: AlexRakia@Yahoo.com & I'll be glad to help you.
AlexRakia does not work on NT...
AnAKin,

listen, I tested it & it runs on Win2k Server
(Win2k server is NT based as Microsoft says).
What else?
It is working very fne for me.

what is not working over there? if you have a problem then please post the problem you got with more detailes.

thanks & appreciations
alex
your code is pausing the main thread for 40 seconds. that is not a good idea for the reason of programs that wcheck programs to freeze. If you use that code user wouldn't realy like to wait 40 seconds with application no responsing and he would probably cole it from CRTL+ALT+DEL list.
In my opinion the best way is to place that if other thread so that it makes you no other problems. That is not hard IMHO.
get one ontimer component

and in  the on timer event do



procedure TForm1.Timer1Timer(Sender: TObject);
begin
  WinExec('c:\BatchFile2.Bat',sw_show);            timer1.enabled:=false;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
timer1.Enabled:=false;
timer1.interval:=20000;
end;


when u like to start the first bat u do

  WinExec('c:\BatchFile1.Bat',sw_show);
  timer1.enabled:=true;




Hello

  Using WinExec isn't recommended, it's available for compatibly with win 32, so you should avoid using it, and use ShellExecute or CreateProcess, for more info refer to win 32 sdk
Avatar of entercite

ASKER

OK,

 Sorry for the delay. I tried the code so far it does not work. Here is what I tried.

procedure TForm1.Button2Click(Sender: TObject);
begin
{wait for each batch file to complete - WinExecAndWait  defined below}
 WinExecAndWait32('C:\Program Files\Apache Tomcat 4.0\bin\shutdown.bat',sw_show);
 update; //refresh form
 WinExecAndWait32('C:\Program Files\Apache Tomcat 4.0\bin\startup.bat',sw_show);
 update;
end;

Also tried...

procedure TForm1.Button1Click(Sender: TObject);
begin
    WinExec('C:\Program Files\Apache Tomcat 4.0\bin\shutdown.bat',sw_show);
    update; //refresh form
   // sleep(5000);
    WinExec('C:\Program Files\Apache Tomcat 4.0\bin\startup.bat',sw_show);
    update;
  //  sleep(5000);
end;

 As you can see the objective of my program is to stop and restart the tomcat server. I had tomcat up and running when I tried executing this program and it launches both bat files but it does not shutdown or restart tomcat.

 Since you all say that the delay is not required I commented this part out.

What is the missing piece to make it work?

-ec
One more comment.

 When the startup bat is launched when I used a mouse click on the icon the command window stays open. The delphi exe I made opens and closes both the command windows they dont stay open.

-ec
ASKER CERTIFIED SOLUTION
Avatar of nex1999
nex1999

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial