Go Premium for a chance to win a PS4. Enter to Win


Launching an external executable.

Posted on 1999-01-17
Medium Priority
Last Modified: 2010-04-06
Hi experts,

there are several ways to start an external executable from the main program.
I created a 32 Bit main program from which I want to launch another 32 Bit
application. I need a solution which works both under WIN95 and WIN98 and WIN NT.

For this purpose, several FAQ's recommend the usage of:

ShellExecute(Application.MainForm.Handle, 'print', , '', '',

I wanted to try it out, but I don't understand the parameter


Does it represent the external executable to be launched?

Moreover I don't know which unit I will have to include in the
uses clause of my demo program, so that my own unit can find

I simply want to do something like:

procedure TfrmMain.Button1Click(Sender: TObject);
  ShellExecute('notepad.exe c:\autoexec.bat');

What is the correct syntax of this ShellExecute statement with all parameters?
Unfortunately, my collection of FAQ's don't provide me with concrete examples,
so I don't understand how I can use this function.

Do you agree that ShellExecute is really the best way to launch another program?
Or should I rather use alternatives like WinExec,ExecAndWait, ShellExecute, CreateProcess.
What is the correct syntax of WinExec,ExecAndWait, ShellExecute, CreateProcess, if I want
to load my autoexec.bat into notepad.exe with the help of these functions.

BTW: I am meanwhile using Delpi 4.0 , standard edition, if that counts.

With kind regards


Question by:mathes
  • 2
  • 2

Accepted Solution

JimBob091197 earned 120 total points
ID: 1362240

ShellExecute is the best method in Win 95/98/NT to execute any file.  The benefit is that it doesn't have to be an EXE file.  It can be DOC, BMP, etc.

The syntax is:

(To answer your question: you have to include the "ShellApi" unit.)

ShellExecute(Self.Handle, 'open', PChar('C:\Windows\Notepad.exe'), PChar('C:\autoexec.bat'), nil, SW_NORMAL);

I use Self.Handle, where Self is the main form, so this is the same as "Application.MainForm.Handle".  This parameter is the window handle of the calling app that can receive error messages if ShellExecute fails, etc.  You can also use GetDesktopWindow.

Another useful way of starting an app is CreateProcess:

  ProcessInfo: TProcessInformation;
  StartUpInfo: TStartUpInfo;
  ZeroMemory(@StartUpInfo, SizeOf(TStartUpInfo));
  with StartUpInfo do
      cb := SizeOf(TStartUpInfo);
      wShowWindow := SW_SHOWNORMAL;;
  CreateProcess(nil, PChar('C:\Windows\Notepad.exe C:\autoexec.bat'), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo);

The benefits of CreateProcess are as follows:

(1)  You can close Notepad politely:

function ThreadWndProc(hWnd: HWND; lParam: LParam): Bool; stdcall;
  // lParam is WM_CLOSE, because that's what we send in when
  // we call EnumThreadWindows (below).
  // Thus, the following will send WM_CLOSE to the window.
  SendMessage(hWnd, lParam, 0, 0);

  // Return True to continue enumeration.
  Result := True;

if not (EnumThreadWindows(ProcessInfo.dwThreadId, @ThreadWndProc, WM_CLOSE)) then
  ShowMessage('EnumThreadWindows failed!');

(2)  You can force Notepad to close (unsaved changes in Notepad are lost):

  TerminateProcess(ProcessInfo.hProcess, 0);

(3)  You can execute Notepad & wait for it to terminate:

  ZeroMemory(@StartUpInfo, SizeOf(TStartUpInfo));
  with StartUpInfo do
      cb := SizeOf(TStartUpInfo);
      wShowWindow := SW_SHOWNORMAL;;
  if (CreateProcess(nil, PChar('C:\Windows\Notepad.exe C:\autoexec.bat'), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo)) then
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);

I usually use ShellExecute because it's pretty simple & can be used on any file (if the file extension is registered).  You can use WinExec, but it's maintained only for compatibility with older versions of Windows.  WinExec will call CreateProcess anyway.

LVL 20

Expert Comment

ID: 1362241
JimBob is completely right. Just one addition. "TerminateProcess" is a quite unclean method of terminating another process. Better would be sending a WM_CLOSE message (like JimBob suggested) if the user may save a changed file or a WM_QUIT message, if the user must not save a changed file.

Regards, Madshi.

Author Comment

ID: 1362242
Dear JimBob,

thank you so far for your help.

Can you please tell me, how I can check the returncode of ShellExecute?
If the returncode is not 0, it is better to display an error message and tell the user what was wrong,
instead of a black screen and leaving the user alone with this problem. Which else values except 0
can ShellExecute return?

And can you please the following lines so that they are accepted  by Delphi 4.0 as
syntactically correct:

WinExec,ExecAndWait, ShellExecute, CreateProcess,

I want to learn the usage of these functions, too. Maybe they are valuable and the best
solution in other situations.

uses ;


WinExec ('notepad.exe c:\autoexec.bat');

uses ;


ExecAndWait ('notepad.exe c:\autoexec.bat');

uses ;


ShellExecute('notepad.exe c:\autoexec.bat');

uses ;


CreateProcess('notepad.exe c:\autoexec.bat');

With kind regards


Expert Comment

ID: 1362243
Hi again

The return values from ShellExecute (as per the Win32 help file) are as follows:

ERROR_FILE_NOT_FOUND      The specified file was not found.
ERROR_PATH_NOT_FOUND      The specified path was not found.
ERROR_BAD_FORMAT          The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
SE_ERR_ACCESSDENIED       The operating system denied access to the specified file.
SE_ERR_ASSOCINCOMPLETE    The filename association is incomplete or invalid.
SE_ERR_DDEBUSY            The DDE transaction could not be completed because other DDE transactions were being processed.
SE_ERR_DDEFAIL            The DDE transaction failed.
SE_ERR_DDETIMEOUT         The DDE transaction could not be completed because the request timed out.
SE_ERR_DLLNOTFOUND        The specified dynamic-link library was not found.
SE_ERR_FNF                The specified file was not found.
SE_ERR_NOASSOC            There is no application associated with the given filename extension.
SE_ERR_OOM                There was not enough memory to complete the operation.
SE_ERR_PNF                The specified path was not found.
SE_ERR_SHARE              A sharing violation occurred.

As for your other questions, I have already given examples of ShellExecute (which "uses ShellApi") and CreateProcess (which "uses Windows), but here is an example for WinExec:

WinExec('C:\Windows\Notepad.exe C:\autoexec.bat', SW_NORMAL);

According to the help file, WinExec returns the following values:
  If the function succeeds, the return value is greater than 31.
  If the function fails, the return value is one of the following error values:
    0 = The system is out of memory or resources.
    ERROR_BAD_FORMAT = The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
    ERROR_FILE_NOT_FOUND = The specified file was not found.
    ERROR_PATH_NOT_FOUND = The specified path was not found.

(I have never used ExecAndWait, but I suspect it is the Windows 3.1 equivalent to the CreateProcess sample I gave previously - the one where you wait for Notepad to terminate.
Similarly, WinExec is (according to the Help file) "provided for compatibility with earlier versions of Windows. For Win32-based applications, use the CreateProcess function".)

As I said before, I nearly always use ShellExecute.  I sometimes use CreateProcess if I want a little more control over the process.



Author Comment

ID: 1362244
Thank you for your help. This is exactly what I was looking for.

With kind regards


Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

773 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