Solved

Waiting till called program finishes

Posted on 2000-03-05
18
229 Views
Last Modified: 2010-04-10
I am writing a C++ program which will call another program using CreateProcess function. I want to halt my first program till the called program finishes and want to execute the next line after that.

How can I do that?

Eg.

CreateProcess("NotePad.exe");
MessageBox("NotePad Closed.");

As soon as Notepad launched my program will be inactive and when the user closes the notepad I want to run the messagebox code?
0
Comment
Question by:ysivaram
  • 6
  • 5
  • 4
  • +1
18 Comments
 
LVL 32

Accepted Solution

by:
jhance earned 100 total points
ID: 2584637
You have to use the information returned by CreateProcess() in the lpProcessInformation struct.  

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;
    HANDLE hThread;
    DWORD dwProcessId;
    DWORD dwThreadId;
} PROCESS_INFORMATION;

the hProcess member of the struct give you the HANDLE of the newly created process.


Now you can use the WaitForSingleObject()
function to keep your creating application waiting until the new process terminates.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2584696
That seems like that should be an answer.

(Assuming of course jhance isn't joking. :-) )
0
 

Expert Comment

by:behjat
ID: 2585076
Note to obtain full information of what is the signiture to CreateProcess and its parameters see MSDN
what you have shown is not correct
any how
This is the

BOOL CreateProcess(  LPCTSTR lpApplicationName,
                         // pointer to name of executable module
  LPTSTR lpCommandLine,  // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
  BOOL bInheritHandles,  // handle inheritance flag
  DWORD dwCreationFlags, // creation flags
  LPVOID lpEnvironment,  // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);

using CreateProcess
then
get the handle of excuted process from
"hProcesInfo" of CreateProcess parameter
that you called
which is a structure with members as follows

typedef struct _PROCESS_INFORMATION { HANDLE hProcess;
HANDLE hThread;    
DWORD dwProcessId;    
DWORD dwThreadId;
} PROCESS_INFORMATION

that is "hProcess"

now use this pic of code

bool  bFlag
DWORD *dwExitCode;
do
{
 bFlag = GetExitCodeProcess(hProcesInfo->hProcess,dwExitCode);
}while(fFlag == true && *dwExitCode != STILL_ACTIVE);

if (fFlag == false)
{
 //Use GetLastError to Obtain the ERROR CODE.
}
else
{
 // Your code that you want to excute after goes here
}

0
 

Expert Comment

by:behjat
ID: 2585085
Note: to obtain full information of what is the signiture to CreateProcess and its parameters see MSDN
what you have shown is not correct
any how
This is the

BOOL CreateProcess(  LPCTSTR lpApplicationName,
                         // pointer to name of executable module
  LPTSTR lpCommandLine,  // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
  BOOL bInheritHandles,  // handle inheritance flag
  DWORD dwCreationFlags, // creation flags
  LPVOID lpEnvironment,  // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);

using CreateProcess
then
get the handle of excuted process from
"hProcesInfo" of CreateProcess parameter
that you called
which is a structure with members as follows

typedef struct _PROCESS_INFORMATION { HANDLE hProcess;
HANDLE hThread;      
DWORD dwProcessId;      
DWORD dwThreadId;
} PROCESS_INFORMATION

that is "hProcess"

now use this pice of code
************************
bool  bFlag
DWORD *dwExitCode;
do
{
 bFlag = GetExitCodeProcess(hProcesInfo->hProcess,dwExitCode);
}while(fFlag == true && *dwExitCode != STILL_ACTIVE);

if (fFlag == false)
{
 //Use GetLastError to Obtain the ERROR CODE.
}
else
{
 // Your code that you want to excute after goes here
}
*******************


 

 
0
 
LVL 22

Expert Comment

by:nietod
ID: 2585146
behjat, did you read the question history?  

The question was already answered and with a better answer--Yours wastes CPU time.
0
 
LVL 32

Expert Comment

by:jhance
ID: 2585563
No I'm not joking this time but unlike that other question, this one does have an answer.

It is clear, however, that behjat either cannot read or is playing answer stealing tricks....

It seems like whenever I try to be courteous to a questioner by not locking the question some jerk like this stomps on the answer with a bogus or duplicate answer.....
0
 
LVL 22

Expert Comment

by:nietod
ID: 2585744
>> I try to be courteous to a questioner by
>> not locking the question some jerk like
>> this stomps on the answer with a bogus
>> or duplicate answe
Not allways.  Only about 75% of the time.  So if you keep doing it, who do you blame?
0
 
LVL 32

Expert Comment

by:jhance
ID: 2585760
I'm about to give up on Experts Exchange "courtesy".  There are too many "piss-ant" expert "wannabes" anymore.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2585851
yeah, and people that post bogus answers too!  :-)
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:ysivaram
ID: 2586097
Yes I prefer Jhance answer.
0
 

Author Comment

by:ysivaram
ID: 2586100
Thank you jhance.

It works fine.
0
 

Expert Comment

by:behjat
ID: 2588951
I do not like time wasters.

I advise you strongly:
firstely
go to school and then read msdn

what I give you as code came from workink soiftware.

Just matter of intrest what do you want to do with your accepted answer
for your information CreateProcess is a nonblocking function
0
 

Author Comment

by:ysivaram
ID: 2589006
nAppHandle = RunProcess(strcat(cLocation, "Notepad.exe"));
      DWORD dRetVal = WaitForSingleObject(nAppHandle, INFINITE);

These two linew as Jhance suggested works fine. Do you see anything wrong there?

In school if they teach us to use pages of code instead of two lines do we need to follow that?
0
 

Author Comment

by:ysivaram
ID: 2589009
Sorry this is the RunProcess function

HANDLE RunProcess(char* cProcess)
{
      STARTUPINFO si;
      PROCESS_INFORMATION pi;
      ZeroMemory( &si, sizeof(STARTUPINFO) );
      ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
      si.cb=sizeof( STARTUPINFO );
      si.dwFlags = STARTF_USESHOWWINDOW;
      si.wShowWindow = SW_MAXIMIZE;
      CreateProcess(cProcess, "", NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi );
      return pi.hProcess;
}
0
 

Expert Comment

by:behjat
ID: 2589055
to nietod
When I saw your question the answer from (jhence) was already there

my assumption was, you were not familiar with synchronization
since you did not accepted the answer thus, I gave you the pice of code that came from bug free software which has been running from at list last 3-years

some idites like the one above does not want to accept there are othere pepole who may know these things as well this is not called stealing the answer.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2589547
>> you were not familiar with synchronization
I'm not sure what your answer has anything to do with syncrhonization.  The best way to synch would be with one of the wait for object functions.

My point was that jhance had posted the answer in terms of content, if not as an actual answer, and that he should post it as an answer.  The line about the joke was because jhance has just posted a bogus function that was to good to be true as an "answer" (in a comment) to a question, and I fell for it.

>> pice of code that came from bug free software
It may work, but it is very very innefficient. There are often many ways to solve a problem, but often one or two ways are far superior to the others.

>> this is not called stealing the answer.
Around here, this is called stealing.  Soem experts post their answers in comments, sometimes because they may be unsure of them and sometimes because they don't want to seem greedy.  But if you see a question that has been answered in terms of content, regardless of whethor or not it has been actually locked, I recommend you treat it as answered.  If you have something to add post it is a comment.  There is no rule currently enforcing this, but if you don't you will have to put up with a lot of "flak" like this.  Its not in your interest.  EE is called a knowledge _community_ and it really works like a community.  The good experts tend to work together to solve problems and to see that things are handled fairly.  Someday you may run in to problems where an client rejects your answer unfairly or where another expert "steals" your points.  You will want support from other experts then...



ysivaram,
   CreateProcess()   opens two handles for you, the process handle, which you return and the thread handle.  It is very important that these handles both be closed when they are no longer needed.  As long as they are open the OS maintains a lot of resources about the process that consume a lot of memory and possibly CPU time at times.  This continues even after the process ends, so you must close these handles.  As the code stands at the moment, you should close the thread handle inside RunProcess() and let the caller close the process handle.
0
 

Author Comment

by:ysivaram
ID: 2589951
nietod

Thanks for your comment I will include that code as well.
0
 

Author Comment

by:ysivaram
ID: 2590025
nietod

Thanks for your comment I will include that code as well.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

746 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now