2010-07-28 29 views
0

J'essaie d'appeler une application FastCGI à partir de .Net - cela signifie que je dois passer un handle à un socket au processus enfant.Erreur lors du passage du socket au processus enfant lors de l'utilisation de l'indicateur STARTF_USESTDHANDLES avec CreateProcess()

Cependant, ce que je vois est que si j'utilise le drapeau STARTF_USESTDHANDLES avec CreateProcess() alors l'application enfant échoue quand elle tente de lire depuis le socket.

J'ai travaillé que je contourner ce problème en ne spécifiant pas STARTF_USESTDHANDLES, mais je voudrais comprendre pourquoi ce qui se passe., d'autant plus que ma compréhension de la documentation MSDN est que je devrait utiliser ce drapeau lors de la redirection des entrées standard.

Ceci est mon application C# (vérification d'erreurs etc ... supprimé par souci de concision)

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

Mon processus enfant est l'exemple d'application FastCGI contenue dans le Windows Azure VS2010 C# code samples, la ligne qui échoue est:

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

Je suis relativement nouveau dans le domaine de la programmation socket et handle, donc tout aperçu de la raison pour laquelle cela se produit serait très apprécié.

Répondre

0

Vous pouvez également essayer de spécifier des poignées pour std err et std out. Ceux-ci doivent être explicitement définis lorsque vous spécifiez STARTF_USESTDHANDLES.

Dans non géré C/C++ cela se fait comme ceci:

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

En dehors de cela, j'attendre à ce que vous devez spécifier une socket déjà connectée - à savoir que vous ne pouvez pas lier.