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

Posted

技术标签:

【中文标题】将 STARTF_USESTDHANDLES 标志与 CreateProcess() 一起使用时将套接字传递给子进程时出错【英文标题】:Error passing socket to child process when using STARTF_USESTDHANDLES flag with CreateProcess() 【发布时间】:2010-07-28 11:38:17 【问题描述】:

我正在尝试从 .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】:

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

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

【讨论】:

以上是关于将 STARTF_USESTDHANDLES 标志与 CreateProcess() 一起使用时将套接字传递给子进程时出错的主要内容,如果未能解决你的问题,请参考以下文章

m 标志和 o 标志将存储在 Linux 中的位置

如何查看哪些标志 -march=native 将激活?

为啥 npm 将命令行标志直接传递给我的脚本?

如何将多个标志作为 Cake 参数传递?

xcode 将编译器标志保存在哪个文件中?

将标志添加到 cffi 编译过程