代码之家  ›  专栏  ›  技术社区  ›  Justin

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

  •  0
  • Justin  · 技术社区  · 16 年前

    我正在尝试从中调用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();
    

    My child进程是包含在 Windows Azure VS2010 C# code samples ,失败的线路是:

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

    我对socket和handle编程都比较陌生,所以如果能深入了解为什么会发生这种情况,我将不胜感激。

    1 回复  |  直到 16 年前
        1
  •  0
  •   villintehaspam    15 年前

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

    除此之外,我希望您需要指定一个已经连接的套接字,也就是说,您不能只是绑定。