• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5011
  • Last Modified:

console app - shellexecute and wait

I use shellexecute to start a .bat file with a parameter.
But I want the app to wait for the .bat file to closed.
How do I do this?

I'm a total newbie to Delphi...
Thanks!
0
Balder1978
Asked:
Balder1978
  • 2
1 Solution
 
CodeBuildersCommented:
The following runs a program unitl the task exits, which should run your .bat file with a parameter until it decides it's ready to close.

Give this a try. (Should be a copy and paste into Delphi)
----------------------------

function WinExecAndWait (FileName : PChar; CommandLine : PChar; 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;
    zCurDir : array[0..255] of char;
    WorkDir : ShortString;
    StartupInfo : TStartupInfo;
    ProcessInfo : TProcessInformation;
    Temp : DWORD;
begin
    StrCopy (zAppName, FileName);
    StrCat (zAppName, CommandLine);
    GetDir (0, WorkDir);
    StrPCopy (zCurDir, WorkDir);
    FillChar (StartupInfo, Sizeof (StartupInfo),#0);
    with StartupInfo do begin
        cb := Sizeof (StartupInfo);
        dwFlags := STARTF_USESHOWWINDOW;
        wShowWindow := Visibility;
    end;
    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 { pointer to PROCESS_INF }
    Result := -1
else
begin
    WaitforSingleObject (ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess (ProcessInfo.hProcess, Temp);
    Result := integer (Temp);
end;
end;

----------------------------

This is how you would run the function:
----------------------------
WinExecAndWait(Pchar(FileString),Pchar(commandstring),SW_HIDE);
----------------------------

You can also call it like this: (make sure you have the Dialogs unit in your uses clause to do it this way).
----------------------------
Var
    Ret: Integer;
Begin
    Ret:=WinExecAndWait(Pchar(FileString),Pchar(commandstring),SW_HIDE);
    If Ret=-1 Then ShowMessage('Error');
End;
----------------------------

Have fun.
0
 
BorlandManCommented:

Use CreateProcess() This is in the Windows API department, at least I would classify it that way.

I happen to be somewhat familiar with Windows apis, so I wrote a function, which makes this a little easier.

Here it is, just paste that into a unit, declare the prototype in the interface section.

hope this helps,
J

----

{////////////////////////////////////////////////////
  CreateProcessAndWait ()

  Purpose:
     This CreateProcess waits nicely and lets
     your application 'breathe' so that repaints
     occur, yet still shuts down the application

  Example Usage:
     CreateProcessAndWait ('C:\Winnt\NotePad.exe')


  Last Update: John Scalco, June 18, 2001, slight mod.

///////////////////////////////////////////////////////}

procedure CreateProcessAndWait (AAppName: string);
var
  pi : TProcessInformation;
  si : TStartupInfo;
  lRetVal : Longint;
begin
  FillChar (si, SizeOf(si), 0);
  si.cb := SizeOf(si);

  // Standard Issue Windows API call.
  CreateProcess(PChar(AAppName), nil, nil, nil, False,
                   NORMAL_PRIORITY_CLASS,nil, nil, si, pi);

  // this allows the application to breathe
  // and still wait until
  // the other application is shut down
   Repeat
     lRetVal := WaitForSingleObject (pi.hProcess, 0);
     Application.ProcessMessages;
   until lRetVal <> 258;

   CloseHandle (pi.hProcess);
end;
0
 
Balder1978Author Commented:
Thanks alot guys!

I copying and pastethe first example, but I really dont know Delphi at all... :(
So could you please implemetns my the code I already have for me? Here is the code I have:

program MBSWSetup;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Registry,
  ShellAPI,
  Windows;

function GetEnvVar(const EnvVar: string): string;
var
BytesNeeded: DWORD;
begin

BytesNeeded := GetEnvironmentVariable(PChar(EnvVar), nil, 0);
if BytesNeeded > 0 then
begin
  SetLength(Result, BytesNeeded - 1);
  GetEnvironmentVariable(PChar(EnvVar), PChar(Result), BytesNeeded);
end
else
  Result := '';
end;

var x:TRegistry;
var Res : string;
begin
x := TRegistry.Create;
x.RootKey := HKEY_LOCAL_MACHINE;
x.OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\',false);
Res := copy(x.ReadString('SourcePath'),1,2);
SetEnvironmentVariable('INSTDRV',pchar(res));
shellexecute(0,'open',pchar(Res + '\' + paramstr(1)),pchar(Res),nil,1);
end.


Thanks again!
0
 
Balder1978Author Commented:
Thanks, I got it working now. :)
0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

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