Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 935
  • Last Modified:

delphi calling a batch file

just a novice in delphi .. started using version 6 today.

wanted to write a program which invokes batch file... so i used the console component. basically just the DPR file using sysutils. but now i am confused by the menu item FILE/NEW/OTHER - which allows me to add  a batch file component into the project.

in a nut shell - how can i have the console application calling a dos bat file?
0
eriklee
Asked:
eriklee
  • 4
  • 3
  • 2
  • +3
3 Solutions
 
Ivanov_GCommented:
uses ...., Windows;

WinExec('your_console_app.bat', SW_SHOWNORMAL);
0
 
Eddie ShipmanAll-around developerCommented:
Use ShellExecute instead, WinExec has been depricated by Microsoft.
0
 
erikleeAuthor Commented:
any idea if the unit calling win/shellExecute will wait for the called xyz.bat to finished first before resuming? if not how do i wait (?) for it to finish first?

thnks
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
erikleeAuthor Commented:
i think i may have found some answers in

http://www.delphipages.com/tips/thread.cfm?ID=62

but looks like so darn many lines of complex coding just to facilitate a 'wait'.
0
 
mornaoCommented:
You could modify the following - it uses a DOS program script and waits for it to end.

procedure TMPCModem.DModem;
var     cmd:pchar;
        dwI:DWORD;
         q :Boolean;
begin
  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
  StartupInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
  StartUpInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE;
  StartUpInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
  StartUpInfo.hStdOutput := GetStdHandle(STD_OUTPUT_HANDLE);
  StartUpInfo.hStdError := GetStdHandle(STD_ERROR_HANDLE);;
  StartupInfo.cb := Sizeof(StartupInfo);
  cmd:=pchar(dataq.database+'\xxx.exe '
    +dataq.database+'\PSxxx.CNF '             // Script
    +'COM'+inttostr(dataq.Modem)             //  Port
    +' 0 '                                                  // Dummy number
    +dataq.database+'\xxx.txt');                 // Text file
// ('xxx.EXE PSxxx.CNF COM1 0 xxx.TXT') but with qualified paths.
  TMPCRem:=true;
  Form19.FlipClose;
  q:=CreateProcess(nil,
                   cmd,
                   nil,
                   nil,
                  true,
    CREATE_NEW_CONSOLE,
                   nil,
                   nil,
           StartUpInfo,
           ProcessInfo);
  if (q=true) then
  begin
    // Following set to 12 minutes for answer restart.
    dwI := WaitForSingleObject(ProcessInfo.hProcess,720000);  // Every 12 minute!
    case dwI of
    WAIT_OBJECT_0: begin
                     if (GetExitCodeProcess(ProcessInfo.hProcess, dwI)) then
                     begin
                       Terminate;
                     end;
                   end
                else begin
    // Send the process an abort message?
                end;
    end;
  end;
end;
0
 
huferryCommented:
uses
  ExtActns;

....... some procedure
begin
 
  with TFileRun.Create(nil) do
  begin
    FileName := 'c:\mybatch.bat';
    Execute;
    Free;
  end;  

end;
0
 
erikleeAuthor Commented:
huferry,
i ran the codes you suggested -- it seems to 'run something' but not the actual batch file nominated. even if i nominate a batch file which does not exists - the process seems to spawn a console screen. i stepped over but can't see anything/error.



(p/s eddieShipman - 50 points is already in the bag for you)
0
 
huferryCommented:
Hello,

I've tested it once more. If the batch file does not exist then the statement will raise an error.
If you don't want a console window to appear just set the property TFileRun.ShowCmd to scHide.

TFileRun is a wrapper for the ShellExecute API function, basically it's the same.

If you want to see what happen to your batch process and do not let the console close by himself, just put the command 'pause' at the end of the batch file.

regards,
Ferry
0
 
Eddie ShipmanAll-around developerCommented:
I'd check for the existance of the file BEFORE trying to actually run it.
0
 
JustinWillisCommented:
To test for end or batch file run I would simply output to a temporary file at the end of the batch file, something like...

time /t>c:\test.tmp

the in your application you could keep checking for the existence of this temporary file, delete it and carry on executing, obviously may want to have it timeout should something go wrong in the batch file, not sure what could but never know huh.

Hope this helps, let me know if I can expand on anything or whether I misunderstood what you were trying to achieve.

Also would use ShellExecute as Eddie suggests.

JustinWillis.
0
 
Eddie ShipmanAll-around developerCommented:
The function posted by eriklee is actually the best way to do it if you must wait for it
to finish before doing something else.
0
 
Eddie ShipmanAll-around developerCommented:
oh, geez, the OP is eriklee...

Anyway, the code on delphipages is really the best way if you need to wait.

I just remembered I had another WinExecAndWait function in my library that
I've used successfully with batch files before

Give this a shot:

function WinExecAndWait32(FileName: string; Visibility: Integer): integer;
 { returns -1 if the Exec failed, otherwise returns the process' exit
   code when the process terminates }
var
  zAppName: array[0..512] of char;
  lpCommandLine: array[0..512] of char;
  zCurDir: array[0..255] of char;
  WorkDir: string;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  StrPCopy(zAppName, '');
  StrPCopy(lpCommandLine, 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, { pointer to command line string }
    lpCommandLine,
    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 := -1 { pointer to PROCESS_INF }
  else begin
    WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sBatchFileName: String;
begin
  sBatchFileName := 'c:\normal.bat';
  if FileExists(SBatchFileName) then
  begin
    WinExecAndWait32(sBatchFileName, SW_HIDE);
  end;
end;
0
 
JustinWillisCommented:
Good to know, yes probably best way to do it if it works ok, will have to stop using temp files.

JustinWillis.
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 4
  • 3
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now