Solved

C++ CreateProcess, wait, main app goes not responding in release mode only

Posted on 2013-01-23
3
990 Views
Last Modified: 2013-01-23
Hello

I'm using the code below to launch an external EXE to my main application (C++ visual studio 2010, MFC project), and wait for that EXE process to be closed by the user before returning control to the main app.

In so far as launching and waiting for it to close, it works as expected. In debug mode, there are no issues. I find that in release mode there is an issue. What happens is that roughly 8 seconds after launching the external EXE, it seems the main app takes on an "hourglass" cursor.. If I do nothing but interact with the child process and then close it, the main application regains control and everything is good. But, if while the child EXE is open and the main application is showing the hourglass I click anywhere within the main application (which shouldn't even be trying to respond to anything) it crashes immediately with basically a "not responding"..

Here is the code (taken from StackOverflow) used to launch the process and wait. I call it with a wait value of 0 for INFINITE but any wait value longer than 5-8 seconds results in the same. Again the "not responding crash" is only in release build, everything is fine in debug mode.

Any ideas? Is there a better way for me to launch an EXE and wait for it to close before proceeding in the main app?

size_t ExecuteProcess(std::wstring FullPathToExe, std::wstring Parameters, size_t SecondsToWait)
{
    size_t iMyCounter = 0, iReturnVal = 0, iPos = 0;
    DWORD dwExitCode = 0;
    std::wstring sTempStr = L"";

    /* Add a space to the beginning of the Parameters */
    if (Parameters.size() != 0)
    {
        if (Parameters[0] != L' ')
        {
            Parameters.insert(0,L" ");
        }
    }

    /* The first parameter needs to be the exe itself */
    sTempStr = FullPathToExe;
    iPos = sTempStr.find_last_of(L"\\");
    sTempStr.erase(0, iPos +1);
    Parameters = sTempStr.append(Parameters);

     /* CreateProcessW can modify Parameters thus we allocate needed memory */
    wchar_t * pwszParam = new wchar_t[Parameters.size() + 1];
    if (pwszParam == 0)
    {
        return 1;
    }
    const wchar_t* pchrTemp = Parameters.c_str();
    wcscpy_s(pwszParam, Parameters.size() + 1, pchrTemp);

    /* CreateProcess API initialization */
    STARTUPINFOW siStartupInfo;
    PROCESS_INFORMATION piProcessInfo;
    memset(&siStartupInfo, 0, sizeof(siStartupInfo));
    memset(&piProcessInfo, 0, sizeof(piProcessInfo));
    siStartupInfo.cb = sizeof(siStartupInfo);

    if (CreateProcessW(const_cast<LPCWSTR>(FullPathToExe.c_str()),
                            pwszParam, 0, 0, false,
                            CREATE_DEFAULT_ERROR_MODE, 0, 0,
                            &siStartupInfo, &piProcessInfo) != false)
    {
         /* Watch the process. */
		DWORD dwWait=INFINITE;
		if (SecondsToWait > 0)
		{
			dwWait = SecondsToWait * 1000;
		}

		dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, dwWait);

    }
    else
    {
        /* CreateProcess failed */
        iReturnVal = GetLastError();
    }

    /* Free memory */
    delete[]pwszParam;
    pwszParam = 0;

    /* Release handles */
    CloseHandle(piProcessInfo.hProcess);
    CloseHandle(piProcessInfo.hThread);

    return iReturnVal;
} 

Open in new window

0
Comment
Question by:PMH4514
  • 2
3 Comments
 
LVL 31

Accepted Solution

by:
Zoppo earned 500 total points
ID: 38810236
Hi PMH4514,

this is a default behavior since Windows XP. I.e. take a look at http://support.microsoft.com/kb/817611/en-us, there you can find this:
If a top-level window stops responding to messages for more than several seconds, the system considers the window to be hung and replaces it with a ghost window that has the same z-order, location, size, and visual attributes. This allows the user to move it, resize it, or even close the application. However, these are the only actions available because the application is actually hung. When in the debugger mode, the system does not generate a ghost window.
So, the trick is to avoid the OS treats your app as 'not responding'.

An easy way to do so is to repeatedly call PeekMessage while waiting for the called process, i.e.:
	MSG msg;
	...
	while( WAIT_TIMOUT == ( dwExitCode = WaitForSingleObject( piProcessInfo.hProcess, 1000 ) )
	{
		// every one second call PeekMessage
		PeekMessage( &msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE );
	}

Open in new window

(This sample doesn't handle the SecondsToWait, you'll have to add it)

Hope that helps,

ZOPPO
0
 

Author Comment

by:PMH4514
ID: 38810246
perfect! I like it when things make sense.

thank you ZOPPO
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 38810262
:o)

you're welcome ...
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone 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

Suggested Solutions

Title # Comments Views Activity
Grammars for C C++ and java 1 138
Which Linux flavors will this run on? 6 101
show out valin of json for debugging in visaul c++ 1 47
C++ Code Issue 4 37
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…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

685 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