|
|
How can i create a child of the child process using CreateProcess function...
I mean up to grandchild level...
|
|
|
|
|
That's a tremendous help. Thanks for sharing.
|
|
|
|
|
In unicode the CreateProcess returns 0 and the error code is 2 which means ERROR_FILE_NOT_FOUND.
Please help to correct the error.
Dija
|
|
|
|
|
How can I get the hand on the text output sent to "stdout" by the process while its running? My console app is sending text to the stdout once in a while (its an old DOS program). I want to hide the console window while its running, but print the output text on my own MFC container (I have a Dialog window with a CRich control that could receive txt data, but I could use a CStatic or some other container, so as long as I can see the text somewhere in my MFC app when my console app runs).
Other question: I'd like to not wait for the process to finish but instead, send a message on termination, then I could capture the termination message in my MFC app and do whatever I have to do when the console is terminated.
Mat
|
|
|
|
|
Good code, helped me today when I was in a rush.
Below is an TCHAR-enabled version (works with _UNICODE and multibyte), in case the author considers updating:
DWORD CreateProcessEx ( LPCTSTR lpAppPath, LPCTSTR lpCmdLine,
BOOL bAppInCmdLine, BOOL bCompletePath,
BOOL bWaitForProcess, BOOL bMinimizeOnWait, HWND hMainWnd ) {
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInformation;
TCHAR szAppPath [ _MAX_PATH ];
TCHAR szCmdLine [ _MAX_PATH ];
TCHAR drive [ _MAX_DRIVE ];
TCHAR dir [ _MAX_DIR ];
TCHAR name [ _MAX_FNAME ];
TCHAR ext [ _MAX_EXT ];
szAppPath[ 0 ] = '\0';
szCmdLine[ 0 ] = '\0';
ZeroMemory( &startupInfo, sizeof( STARTUPINFO ));
startupInfo.cb = sizeof( STARTUPINFO );
ZeroMemory( &processInformation, sizeof( PROCESS_INFORMATION ));
if ( bCompletePath ) {
GetModuleFileName( GetModuleHandle( NULL ), szAppPath, _MAX_PATH );
_tsplitpath( szAppPath, drive, dir, NULL, NULL );
_tsplitpath( lpAppPath, NULL, NULL, name, ext );
_tmakepath ( szAppPath, drive, dir, name, _tcslen( ext ) ? ext : _T(".exe") );
}
else _tcscpy( szAppPath, lpAppPath );
if ( bAppInCmdLine ) {
_tcscpy( szCmdLine, _T("\"") );
_tcscat( szCmdLine, szAppPath );
_tcscat( szCmdLine, _T("\"") );
}
if ( lpCmdLine ) {
_tcscat( szCmdLine, lpCmdLine );
}
DWORD dwExitCode = -1;
if ( CreateProcess( bAppInCmdLine ? NULL: szAppPath, // lpszImageName
szCmdLine, // lpszCommandLine
0, // lpsaProcess
0, // lpsaThread
FALSE, // fInheritHandles
DETACHED_PROCESS, // fdwCreate
0, // lpvEnvironment
0, // lpszCurDir
&startupInfo, // lpsiStartupInfo
&processInformation // lppiProcInfo
)) {
if ( bWaitForProcess ) {
if ( bMinimizeOnWait )
if ( IsWindow( hMainWnd )) ShowWindow( hMainWnd, SW_MINIMIZE );
#ifdef __AFX_H__
else AfxGetMainWnd()->ShowWindow( SW_MINIMIZE );
#endif
WaitForSingleObject( processInformation.hProcess, INFINITE );
if ( bMinimizeOnWait )
if ( IsWindow( hMainWnd )) ShowWindow( hMainWnd, SW_RESTORE );
#ifdef __AFX_H__
else AfxGetMainWnd()->ShowWindow( SW_RESTORE );
#endif
GetExitCodeProcess( processInformation.hProcess, &dwExitCode );
}
else {
CloseHandle( processInformation.hThread );
CloseHandle( processInformation.hProcess );
dwExitCode = 0;
}
}
return dwExitCode;
}
|
|
|
|
|
Thanx, this will help me alot.
The only programmers that are better than C programmers are those who code in 1's and 0's.....
Programm3r
|
|
|
|
|
|
I used CreateProcess() to call a *.exe file,
I use TerminateProcess() to terminate the *.exe.
But on the MSDN ,it says the TerminateProcess() is a dangerous funtion .
So i want to know what is the best way to terminate the *.exe file ,
PLS give me any suggestion!
Thank ! Best regards !
|
|
|
|
|
yes, I use this function to call my other external application. but I found it could occure a failure (return FALSE)after CreateProcess().
using the debug I could the the dwThreadID returned is 0x0000002 but other hadle all are 0x00000. but when I called secondly, it will return true.
I call the GetLastError(), it showed "2" :
2: ERROR_FILE_NOT_FOUND The system cannot find the file specified
I confirm I do it the correct the file name .
I don't know why it occured
maybe there has some bugs on WinCE 4.2 filesystem.
sly zhang
-- modified at 21:38 Thursday 23rd March, 2006
|
|
|
|
|
Why is there no closeHandle in 'if ( bWaitForProcess ) { ... }' clause...?
----------------------------------------------------------------------------------
if ( bWaitForProcess ) {
if ( bMinimizeOnWait )
//...
//...
//...
GetExitCodeProcess( processInformation.hProcess, &dwExitCode );
// CloseHandle() is needed...?
// CloseHandle( processInformation.hThread );
// CloseHandle( processInformation.hProcess );
}
else {
CloseHandle( processInformation.hThread );
CloseHandle( processInformation.hProcess );
dwExitCode = 0;
}
----------------------------------------------------------------------------------
|
|
|
|
|
Hi can you please tell me the maximum command line length that CreateProcess accepts. In your code ita _MAX_PATH, but on some sites i have its mentioned as 32K. Will you please clarify on this? Its becoming very confusing, because in my code i can pass a command line of about 3000 characters to a batch file using CreateProcess.
Best regards,
|
|
|
|
|
That the limit of _MAX_PATH is true for Windows 2000 only. This limit should not be present. You will need to use a safer string class or up the limit to a large value (eg. 8-16k). Luckily VS2005 warned me about that buffer overflow as I had not read the code to check for such bugs.
|
|
|
|
|
Hi, i need to startup an html text as HELP for one application, i work in VisualStudio 6.
Could you esplain me how to do?
thanks
|
|
|
|
|
Hi,
Sometimes the User can switch to thrid application and when closing the Child Process the Main Window is Not the Topmost Window.
There are API's like SetForgroundWindow or BringWindowToTop, but its not working as per the New Design of Win2000 etc , but works in Win95.
What's the solution for it?
Small Problem Big Solution, Big Problem Small Solution
|
|
|
|
|
Thank you, Boherna. This code was a lot of help for my electrical engineering senior project (voice recognition in matlab - compiled to exe and embedded in a visual C++ program).
Quick question - is there any way to have the Process open? I have a commandline exe that I run with your code, but I'd like the window of that command line to appear instead of be hidden.
Thanks again.
|
|
|
|
|
Boherna,
Do you know how to get the window handle of the child window created by the CreateProcess Instruction to Relocate, Resize, etc. the child windows.
Thanks for your help.
|
|
|
|
|
In your opening sentence, you said, "I needed to wait until an external application finished processing some data ... (etc.) to prevent the user from doing anything else before the results were available."
I am not exactly clear what you mean by that, because it sounds to me as though, by activating this newly created Process, you'll be putting aside the previous Process from functioning any further until the newly created Process has completed its work and returned.
If that is true, then the newly created Process will (in a way) have focus, allowing the user to work with it, then upon completion, resume to the previous Process (that will have been waiting all the while).
So I put the assertion to the test and from your sample application, browsed to a test application that required inputting some data.
Upon activating the test application, in less than a quarter of a second, the newly created Process returned to the waiting Process without giving me a chance to interface with the test application!!
Shouldn't focus have been granted to the newly created Process to do its work, and if that work required user interface, then it should have waited for the user to signal completion of activity before returning to the waiting Process? Isn't that the idea, or am I missing out on something?
William
Fortes in fide et opere!
|
|
|
|
|
Hi William,
When using the supplied demo application if you browse to any other program that needs user input (e.g, Microsoft Word, Notepad, Paint, etc), doesn't it stay minimized until the external program/process exits?
Thanks / Boherna
|
|
|
|
|
The short answer to your question is, "No, it didn't."
The long answer is, I didn't try any of the application you mentioned (Microsoft Word, Notepad, etc.). I used a similar application I knew for sure needed user interface, which the user would have to signal when finished. The point is, I saw your sample minimized, and almost immediately (like in a small fraction of a second), maximized itself back without even as much as a pause to indicate it may have been trying to activate the external Process, but couldn't do so. (I am talking like a 'bounce', where your sample 'bounced' down (by minimizing itself), and immediately 'bounced' back up.) No waiting! No anything!
William
Fortes in fide et opere!
|
|
|
|
|
If the demo is minimized and immediately restored is because by some reason the child process handle was signaled causing the:
...<br />
WaitForSingleObject( processInformation.hProcess, INFINITE );<br />
...
function call to quickly return.
Perhaps the application you are running exits immediately after launching another new process. In this case, the demo will behave as you describe.
Finally, could you try with any of the applications I mentioned to see if the demo works as expected?
Boherna
|
|
|
|
|
It is possible that the .exe file you try to launch is not found or something else.
You can get the Last Error and display the meaningful text with :
GetLastError() and FormatMessage()
This might give you a clue as to why the CreateProcess goes in and out so quickly.
The following add-on will popup a msgBox showing the reason why CreateProcess failed.
-------------------------------------------------------
if ( CreateProcess( bAppInCmdLine ? NULL: szAppPath, // lpszImageName
szCmdLine, // lpszCommandLine
0, // lpsaProcess
0, // lpsaThread
FALSE, // fInheritHandles
DETACHED_PROCESS, // fdwCreate
0, // lpvEnvironment
0, // lpszCurDir
&startupInfo, // lpsiStartupInfo
&processInformation // lppiProcInfo
))
{
.. wait object stuff in here (see original CodeProject)
}
else // if CreateProcess failed
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
}
-----------
|
|
|
|
|
It is possible that the .exe file you try to launch is not found or something else.
You can get the Last Error and display the meaningful text with :
GetLastError() and FormatMessage()
This might give you a clue as to why the CreateProcess goes in and out so quickly.
The following add-on will popup a msgBox showing the reason why CreateProcess failed.
-------------------------------------------------------
if ( CreateProcess( bAppInCmdLine ? NULL: szAppPath, // lpszImageName
szCmdLine, // lpszCommandLine
0, // lpsaProcess
0, // lpsaThread
FALSE, // fInheritHandles
DETACHED_PROCESS, // fdwCreate
0, // lpvEnvironment
0, // lpszCurDir
&startupInfo, // lpsiStartupInfo
&processInformation // lppiProcInfo
))
{
.. wait object stuff in here (see original CodeProject)
}
else // if CreateProcess failed
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
}
-----------
|
|
|
|
|