Ошибка передачи сокета дочернему процессу при использовании флага STARTF_USESTDHANDLES с CreateProcess () - PullRequest
0 голосов
/ 28 июля 2010

Я пытаюсь вызвать приложение FastCGI из .Net - это означает, что мне нужно передать дескриптор сокета дочернему процессу.

Однако, что я вижу, так это то, что если я использую флаг STARTF_USESTDHANDLES с CreateProcess(), то дочернее приложение завершается ошибкой при попытке чтения из сокета.

Я понял, что обхожу это, не указав STARTF_USESTDHANDLES, но я хотел бы понять , почему это происходит. , особенно в моем понимании документация MSDN заключается в том, что я должен использовать этот флаг при перенаправлении стандартных входных данных.

Это мое приложение на C # (проверка ошибок и т. Д. Для краткости удалено)

string command = @"FastCGI.exe";

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Any, 8221));

// Duplicate the socket handle so that it is inheritable
SafeFileHandle childHandle;
NativeMethods.DuplicateHandle(NativeMethods.GetCurrentProcess(), new SafeFileHandle(listener.Handle, false), NativeMethods.GetCurrentProcess(), out childHandle, 0, true, NativeMethods.DUPLICATE_SAME_ACCESS);

NativeMethods.STARTUPINFO startupInfo = new NativeMethods.STARTUPINFO();
startupInfo.hStdInput = childHandle;

// Uncommenting the following line causes the problem
//startupInfo.dwFlags = NativeMethods.STARTF_USESTDHANDLES;

// Start the child process
NativeMethods.PROCESS_INFORMATION processInformation;
NativeMethods.CreateProcess(null, command, null, null, true, 0, IntPtr.Zero, null, startupInfo, out processInformation);

// To prevent the process closing the socket handle
Console.ReadKey();

Мой дочерний процесс - это пример приложения FastCGI, содержащийся в примерах кода Windows Azure VS2010 C # , строка, которая завершается ошибкой:

BOOL ret = ReadFile( hStdin, pBuffer, dwSize, &nNumberOfBytes, NULL );
if(!ret)
{
    // dw = 87 (ERROR_INVALID_PARAMETER)
    DWORD dw = GetLastError();
}

Я относительно новичок в программировании на сокетах и ​​дескрипторах, поэтому любое понимание того, почему это происходит, будет высоко оценено.

1 Ответ

0 голосов
/ 20 декабря 2010

Возможно, вы захотите указать дескрипторы для std err и std out.Они должны быть явно установлены, когда вы указываете STARTF_USESTDHANDLES.

В неуправляемом C / C ++ это делается так:

STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
...
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = myInheritableHandle;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

Кроме того, я ожидаю, что вам нужно указатьуже подключен сокет - т.е. вы не можете просто привязать.

...