I'm writing a program that opens another console application with redirected input and output handles. I don't get any errors when I run this, but the console closes immediately, despite the system("pause") at the end. With the current solution, I have it redirecting to files, but another solution using pipes (commented out) yielded the same results. Here is the relevant code:

edit: I should mention that hStdIn, hStdOut, hStdErr, and hChildProcess are globally defined handles.

BOOL createProcess(WCHAR commandLine[])
{
	//HANDLE hStdInRead;
	//HANDLE hStdInWriteTmp;
	//HANDLE hStdOutWrite;
	//HANDLE hStdOutReadTmp;
	//HANDLE hStdErrWrite;
	//HANDLE hStdErrReadTmp;
	SECURITY_ATTRIBUTES sa;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));

	/*sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;

	if(!CreatePipe(&hStdInRead,
				   &hStdInWriteTmp,
				   &sa,
				   0))
	{
		error(L"Failed to create stdin handle.");
		return FALSE;
	}

	if(!CreatePipe(&hStdOutReadTmp,
				   &hStdOutWrite,
				   &sa,
				   0))
	{
		error(L"Failed to create stdout handle.");
		return FALSE;
	}

	if(!CreatePipe(&hStdErrReadTmp,
			   &hStdErrWrite,
			   &sa,
			   0))
	{
		error(L"Failed to create stderr handle.");
		return FALSE;
	}

	// create non-inheritable duplicates of the handles

	if(!DuplicateHandle(GetCurrentProcess(),
						hStdInWriteTmp,
						GetCurrentProcess(),
						&hStdIn,
						NULL,
						FALSE,
						DUPLICATE_SAME_ACCESS))
	{
		error(L"Failed to duplicate stdin handle.");
		return FALSE;
	}

	if(!DuplicateHandle(GetCurrentProcess(),
						hStdOutReadTmp,
						GetCurrentProcess(),
						&hStdOut,
						NULL,
						FALSE,
						DUPLICATE_SAME_ACCESS))
	{
		error(L"Failed to duplicate stdout handle.");
		return FALSE;
	}

	if(!DuplicateHandle(GetCurrentProcess(),
						hStdErrReadTmp,
						GetCurrentProcess(),
						&hStdErr,
						NULL,
						FALSE,
						DUPLICATE_SAME_ACCESS))
	{
		error(L"Failed to duplicate stderr handle.");
		return FALSE;
	}

	// close inheritable pipes
	CloseHandle(hStdInWriteTmp);
	CloseHandle(hStdOutReadTmp);
	CloseHandle(hStdErrReadTmp);*/

	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;

	// try to create a new file first, if that doesnt't work open the existing one

	hStdIn = CreateFile(L"Input.txt",
						GENERIC_WRITE,
						FILE_SHARE_READ,
						&sa,
						CREATE_NEW,
						FILE_ATTRIBUTE_NORMAL, //FILE_FLAG_DELETE_ON_CLOSE,
						NULL);
	if(!hStdIn)
	{
		hStdIn = CreateFile(L"Input.txt",
							GENERIC_WRITE,
							FILE_SHARE_READ,
							&sa,
							TRUNCATE_EXISTING,
							FILE_ATTRIBUTE_NORMAL, //FILE_FLAG_DELETE_ON_CLOSE,
							NULL);
		if(!hStdIn)
		{
			error(L"Failed to create or open input file.");
			return FALSE;
		}
	}

	hStdOut = CreateFile(L"Output.txt",
						GENERIC_READ,
						FILE_SHARE_WRITE,
						&sa,
						CREATE_NEW,
						FILE_ATTRIBUTE_NORMAL, //FILE_FLAG_DELETE_ON_CLOSE,
						NULL);
	if(!hStdOut)
	{
		hStdOut = CreateFile(L"Output.txt",
							GENERIC_READ,
							FILE_SHARE_WRITE,
							&sa,
							TRUNCATE_EXISTING,
							FILE_ATTRIBUTE_NORMAL, //FILE_FLAG_DELETE_ON_CLOSE,
							NULL);
		if(!hStdOut)
		{
			error(L"Failed to create or open output file.");
			return FALSE;
		}
	}

	hStdErr = CreateFile(L"Error.txt",
						GENERIC_READ,
						FILE_SHARE_WRITE,
						&sa,
						CREATE_NEW,
						FILE_ATTRIBUTE_NORMAL, //FILE_FLAG_DELETE_ON_CLOSE,
						NULL);
	if(!hStdErr)
	{
		hStdErr = CreateFile(L"Error.txt",
							GENERIC_READ,
							FILE_SHARE_WRITE,
							&sa,
							TRUNCATE_EXISTING,
							FILE_ATTRIBUTE_NORMAL, //FILE_FLAG_DELETE_ON_CLOSE,
							NULL);
		if(!hStdErr)
		{
			error(L"Failed to create or open input file.");
			return FALSE;
		}
	}

	ZeroMemory(&si, sizeof(STARTUPINFO));
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_SHOW; //SW_HIDE;
	si.hStdInput = hStdIn;
	si.hStdOutput = hStdOut;
	si.hStdError = hStdErr;

	if(!CreateProcess(NULL,
					  commandLine,
					  NULL,
					  NULL,
					  TRUE,
					  NORMAL_PRIORITY_CLASS,
					  NULL,
					  NULL,
					  &si,
					  &pi))
	{
		error(L"Failed to create process.");
		return FALSE;
	}

	/*// close the child process' handles
	CloseHandle(hStdInRead);
	CloseHandle(hStdOutWrite);
	CloseHandle(hStdErrWrite);*/

	CloseHandle(pi.hThread);
	hChildProcess = pi.hProcess;

	return TRUE;
}

I can post the application it opens if necessary, but I doubt it would be. It works perfectly on its own.

I should also mention that if I leave out the STARTF_USESTDHANDLES flag in the STARTUPINFO structure, it works fine (except that, obviously, the i/o isn't redirected).

I solved this myself. I'm not sure why the file idea didn't work, but going back to the pipes idea, I just passed the console the wrong handles. For any others having the problem, make sure you give it the stdInRead handle, and the stdOutWrite and stdErrWrite handles.

This article has been dead for over six months. Start a new discussion instead.