0

.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#コードサンプルに含まれているサンプルFastCGIアプリケーションですが、失敗する行は次のとおりです。

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

私はソケットプログラミングとハンドルプログラミングの両方に比較的慣れていないので、なぜこれが起こるのかについての洞察をいただければ幸いです。

4

1 に答える 1

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);

それとは別に、すでに接続されているソケットを指定する必要があると思います-つまり、バインドすることはできません。

于 2010-12-20T12:06:24.550 に答える