Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
How can I properly use CreateProcess to instantiate a new process? Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi 2.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			 Author: Lou Adler

How can I properly use CreateProcess to instantiate a new process?


What's a Process

Before I give you the code to execute a program in Windows with CreateProcess, I 
feel we should delve a bit into the concept of a what a process is. With Win32, 
Microsoft changed nomenclature to help make the distinction of new concepts more 
clear for developers. Unfortunately, not everyone understood it - including myself 
at first. In Win16 a process was the equivalent to an application. That was just 
fine because Windows 3.1 was (and still is) a non-preemptive multitasking system - 
there's no such thing as threads.

But with the move to Win32 (Win95 and NT), many people have made the mistake of 
equating a thread to a process. It's not an unusual thing considering the 
familiarity with an older concept. However, threads and processes are both distinct 
concepts and entities. Threads are children of processes; while processes, on the 
other hand, are inert system entities that essentially do absolutely nothing but 
define a space in memory for threads to run - threads are the execution portion of 
a process and a process can have many threads attached to it. That's it. I won't go 
into the esoteric particulars of memory locations and addressable space and the 
like. Suffice it to say that processes are merely memory spaces for threads.

That said, executing a program in Win32 really means loading a process and its 
child thread(s) in memory. And the way you do that in Win32 is with CreateProcess. 
Mind you, for backward compatibility, the Win16 calls for executing programs, 
WinExec and ShellExecute are still supported in the Windows API, and still work. 
But for 32-bit programs, they're considered obsolete. Okay, let's dive into some 

The following code utilizes the CreateProcess API call, and will execute any 
program, DOS or Windows.
2   {Supply a fully qualified path name in ProgramName}
4   procedure ExecNewProcess(ProgramName: string);
5   var
6     StartInfo: TStartupInfo;
7     ProcInfo: TProcessInformation;
8     CreateOK: Boolean;
9   begin
11    { fill with known state }
12    FillChar(StartInfo, SizeOf(TStartupInfo), #0);
13    FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
14    StartInfo.cb := SizeOf(TStartupInfo);
16    CreateOK := CreateProcess(PChar(ProgramName), nil, nil, nil, False,
18      nil, nil, StartInfo, ProcInfo);
20    { check to see if successful }
21    if CreateOK then
22      //may or may not be needed. Usually wait for child processes
23      WaitForSingleObject(ProcInfo.hProcess, INFINITE);
24  end;

Okay, while the code above works just fine for executing an application, one my 
readers pointed out that it doesn't work with programs that include a command line 
argument. Why? Because CreateProcess' first parameter expects a fully qualified 
program name (path\executable) and nothing else! In fact, if you include a command 
line in that parameter, CreateProcess will do nothing. Yikes! In that case, you 
have to use the second argument. In fact, you can use the second parameter even for 
just executing a program with no command line. Given that, ExecNewprocess would be 
changed as follows:

{Supply a fully qualified path name in ProgramName
 and any arguments on the command line. As the help file
 states: "If lpApplicationName is NULL, the first white space-delimited
 token of the command line specifies the module name..." In English,
 the characters before the first space encountered (or if no space is
 encountered as in a single program call) is interpreted as the
 EXE to execute. The rest of the string is the argument line.}

25  procedure ExecNewProcess(ProgramName: string);
26  var
27    StartInfo: TStartupInfo;
28    ProcInfo: TProcessInformation;
29    CreateOK: Boolean;
30  begin
32    { fill with known state }
33    FillChar(StartInfo, SizeOf(TStartupInfo), #0);
34    FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
35    StartInfo.cb := SizeOf(TStartupInfo);
37    CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil, False,
39      nil, nil, StartInfo, ProcInfo);
41    { check to see if successful }
42    if CreateOK then
43      //may or may not be needed. Usually wait for child processes
44      WaitForSingleObject(ProcInfo.hProcess, INFINITE);
45  end;

I know, it's a bit of complex call. And the documentation and online help aren't much help in getting information on it. I think the biggest problem people have working with the WinAPI through Delphi is that the help topics are directed towards C/C++ programmers, not Delphi programmers. So on the fly, Delphi programmers have to translate the C/C++ conventions to Delphi. This has caused a lot of confusion for me and others who have been exploring threads and processes. With luck, we'll see better documentation emerge from either Borland or a third-party source.

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC