Click here to Skip to main content
11,505,123 members (69,921 online)
Click here to Skip to main content

A newbie's elementary guide to spawning processes

, 2 Aug 2002 Ms-PL 417.4K 125
Rate this:
Please Sign up or sign in to vote.
Gives an elementary introduction to the use of ShellExecute/ShellExecuteEx, CreateProcess, WaitForSingleObject. How to bring up the Find window, the Properties window.

Introduction

Often, we find questions coming from newbies on how to spawn a new process, how to open a particular document with the program associated with it, how to launch a web site, how to bring up the mail client's compose window, how to wait for a program to finish, how to print a file etc. Quite a few of these can be accomplished using the CreateProcess call. Unfortunately newbies often find that CreateProcess is not exactly the easiest of calls to understand. But the very good news for newbies is that you can use some of the shell functions available through shell32.dll to accomplish the above jobs.

This article is a sort of miniature FAQ that gives you short code snippets that detail how a particular task can be done. You must look up the functions discussed here on MSDN. And I'd be glad if people can send in more questions on similar lines that might fit in here. I also give an ultra brief introduction to CreateProcess at the end of the article. It is highly insufficient an approach, but I do think it will serve a newbie as an easy stepping block.

ShellExecute and what it does for you

This function is declared in Shellapi.h which you will need to include. You will also have to link with Shell32.lib. ShellExecute is one of the API calls that really saves you a lot of effort. We'll go through the usage of the function through the mini FAQ format. Look up the function on MSDN to get an idea of what each of the parameters mean.

Q: How do I start an application under windows?

A: Simple. Just call ShellExecute, passing the full path of the file name you want to execute.

ShellExecute(this->m_hWnd,"open","calc.exe","","", SW_SHOW );

You can even pass parameters to the application as shown below :-

ShellExecute(this->m_hWnd,"open","notepad.exe",
    "c:\\MyLog.log","",SW_SHOW );

As you can see, I haven't passed the full path of the programs. ShellExecute will look into the PATH environment variable if you don't specify the full path.

Q: I want to open a particular document using the program associated with that document type.

A: You can pass the path of a document to ShellExecute and ShellExecute will open the file in it's associated program. Easy, huh?

ShellExecute(this->m_hWnd,"open",
    "c:\\abc.txt","","",SW_SHOW );

Q: I want to launch my home page in a browser window programmatically.

A: Boy! If you only knew how easy this is. Simply pass the URL to ShellExecute. I bet you have a caustic smile on your lips now as if to say, "Damn! I don't believe this."

ShellExecute(this->m_hWnd,"open",
    "http://www.google.com","","", SW_SHOW );

Q: How do I launch the compose window of the default email client with an address I specify as the To: address?

A: This time we pass a mailto link to ShellExecute.

ShellExecute(this->m_hWnd,"open",
    "mailto:nishinapp@yahoo.com","","", SW_SHOW );

Q: My boss asked me to print that license-agreement text file from the program.

A: Have no fear, ShellExecute is here. [I hope I am not over-doing this]

ShellExecute(this->m_hWnd,"print",
    "c:\\abc.txt","","", SW_HIDE);

Q: I want to bring up the Windows Find window on a particular folder.

A: We use the find verb as the operation parameter and we have the Windows Find window open up with the directory we have specified. This can be rather handy if you want to allow users to find some file within some folder. Just ask them for their folder and pop up a Find Window which has their folder as the root folder.

ShellExecute(m_hWnd,"find","d:\\nish",
    NULL,NULL,SW_SHOW);

Big Brother - ShellExecuteEx

ShellExecuteEx is a more flexible call, in that it allows us to retrieve information about the program we just spawned. You'll need to fill up the SHELLEXECUTEINFO structure and pass it's address to ShellExecuteEx. Please lookup both on your copy of MSDN.

Q: How do I start a program, and halt execution of my current program, till that program exits?

A: You start the program using ShellExecuteEx and use WaitForSingleObject on the process handle.

SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";		
ShExecInfo.lpParameters = "";	
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;	
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);

Q: I want to show the File or Folder properties window for a file or a folder.

A: This time what we do is to pass properties as the operation verb. We also need to specify SEE_MASK_INVOKEIDLIST as the fmask parameter of the SHELLEXECUTEINFO structure. That's why we have to use ShellExecuteEx here instead of ShellExecute. I owe this tip to David Lowndes, Microsoft MVP because it was David who helped me with that tip about the SEE_MASK_INVOKEIDLIST flag.

SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\\"; //can be a file as well
ShExecInfo.lpParameters = ""; 
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL; 
ShellExecuteEx(&ShExecInfo);

CreateProcess - an ultra brief introduction

The CreateProcess function is part of Kernel32.dll. Windows uses this call to create a new process and a primary thread for the new process. The primary thread then starts executing the specified executable. Normally, if this is a C++  program, execution starts with your WinMain [actually prior to this the CRT library is loaded and initialized]. For a more comprehensive tutorial on the use of CreateProcess, I recommend that you read Joseph M Newcomer's article, An Introduction to Processes: Asynchronous Process Notification.

PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("c:\\winnt\\notepad.exe", NULL, 
    NULL,NULL,FALSE,0,NULL,
    NULL,&StartupInfo,&ProcessInfo))
{ 
    WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
}  
else
{
    MessageBox("The process could not be started...");
}

As you can observe, I am using WaitForSingleObject on the process handle. But since CreateProcess creates a thread object in addition to the process object, I might as well have waited on the thread handle as in :-

WaitForSingleObject(ProcessInfo.hThread,INFINITE);

This might cause problems though if, for some reasons, one or more of your secondary threads are still active even after the main thread finishes. MSDN says that a process is fully terminated only when all it's threads have ceased execution. So I recommend that you wait on the process handle rather than on the thread handle.

Last Updates

  • Aug 03 2002 - Added tip to bring up the Find window
  • Aug 03 2002 - Added tip to bring up the Properties window

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Nish Nishant

United States United States
Nish Nishant is a Software Architect/Consultant based out of Columbus, Ohio. He has over 15 years of software industry experience in various roles including Lead Software Architect, Principal Software Engineer, and Product Manager. Nish is a recipient of the annual Microsoft Visual C++ MVP Award since 2002 (13 consecutive awards as of 2014).

Nish is an industry acknowledged expert in the Microsoft technology stack. He authored
C++/CLI in Action for Manning Publications in 2005, and had previously co-authored
Extending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition, he has over 140 published technology articles on CodeProject.com and another 250+ blog articles on his
WordPress blog. Nish is vastly experienced in team management, mentoring teams, and directing all stages of software development.

Contact Nish : You can reach Nish on his google email id voidnish.

Website and Blog

Comments and Discussions

 
Questionmysql Command not working using ShellExecute Pin
saraswathisrinath20-Mar-15 19:54
membersaraswathisrinath20-Mar-15 19:54 
QuestionMultiple files property dialog Pin
ibrahimahmed44323-Jan-13 11:32
memberibrahimahmed44323-Jan-13 11:32 
GeneralMy vote of 5 Pin
Member 43208446-Nov-11 0:52
memberMember 43208446-Nov-11 0:52 
GeneralShellExecuteEx in VB to launch an exe Pin
jerryj22-Oct-12 11:14
memberjerryj22-Oct-12 11:14 
GeneralMy vote of 5 Pin
matelich5-Sep-10 19:07
membermatelich5-Sep-10 19:07 
GeneralURLs with percentage char Pin
LejonO10-May-08 23:34
memberLejonO10-May-08 23:34 
QuestionShellExecututeEx and impersonate user Pin
padvit7-May-08 9:41
memberpadvit7-May-08 9:41 
GeneralShellExecuteEx Pin
Gord22-Aug-07 7:17
memberGord22-Aug-07 7:17 
GeneralExcellent work buddy Pin
vincent73725-Jul-07 2:13
membervincent73725-Jul-07 2:13 
GeneralShellExecuteEx code flawed Pin
andrewtruckle29-May-07 4:13
memberandrewtruckle29-May-07 4:13 
QuestionDifferent Working Directory? Pin
Neo5537800829-Apr-07 18:44
memberNeo5537800829-Apr-07 18:44 
GeneralRename Folder.....thanks! Pin
nguyenkimso24-Apr-07 22:54
membernguyenkimso24-Apr-07 22:54 
GeneralCalling jar files using ShellExecute() Pin
Nikhil Trivedi24-Apr-07 21:25
memberNikhil Trivedi24-Apr-07 21:25 
GeneralSome thing happened to my friend Pin
grin_t22-Feb-07 20:27
membergrin_t22-Feb-07 20:27 
GeneralRe: Some thing happened to my friend Pin
ThatsAlok1-Apr-07 22:45
memberThatsAlok1-Apr-07 22:45 
GeneralRe: Some thing happened to my friend Pin
grin_t6-Apr-07 21:36
membergrin_t6-Apr-07 21:36 
QuestionCan I use the a ShellExecute function call from a dll? Pin
shaymoh26-Jan-07 8:07
membershaymoh26-Jan-07 8:07 
QuestionHow can i spawn a process in a desired window? Pin
lata07mahi15-Oct-06 20:47
memberlata07mahi15-Oct-06 20:47 
AnswerRe: How can i spawn a process in a desired window? Pin
ThatsAlok1-Apr-07 22:50
memberThatsAlok1-Apr-07 22:50 
QuestionURL to createprocess Pin
dipali_be200325-Sep-06 22:32
memberdipali_be200325-Sep-06 22:32 
AnswerRe: URL to createprocess Pin
ThatsAlok1-Apr-07 22:48
memberThatsAlok1-Apr-07 22:48 
GeneralThanks! Pin
robosport2-Jun-06 17:13
memberrobosport2-Jun-06 17:13 
GeneralPassing spaces in folder names Pin
David_Leikis16-May-06 6:04
memberDavid_Leikis16-May-06 6:04 
GeneralRe: Passing spaces in folder names Pin
Nishant Sivakumar16-May-06 13:37
staffNishant Sivakumar16-May-06 13:37 
GeneralOne process that handles all future requests Pin
BillMcNeil27-Mar-06 4:52
memberBillMcNeil27-Mar-06 4:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 3 Aug 2002
Article Copyright 2002 by Nish Nishant
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid