将STARTF_USESTDHANDLES标志与CreateProcess()一起使用时,将套接字传递给子进程时出错

时间:2010-07-28 11:38:18

标签: c# sockets handle createprocess

我试图从.Net调用FastCGI应用程序 - 这意味着我需要将一个句柄传递给子进程的套接字。

然而,我所看到的是,如果我将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();

我的子进程是Windows Azure VS2010 C# code samples中包含的示例FastCGI应用程序,失败的行是:

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

我对套接字和句柄编程都比较陌生,所以任何了解这种情况的原因都会非常感激。

1 个答案:

答案 0 :(得分:0)

您可能还想尝试为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);

除此之外,我希望你需要指定一个已连接的套接字 - 即你不能只绑定。