2012-02-20 9 views
10

¿Cuál es el método para obtener el valor devuelto de un subproceso dentro de Windows? Parece que ShellExecute() es más fácil de usar que CreateProcess(), pero según la lectura que he hecho hasta ahora, ninguno indica cómo verificar el valor de retorno del proceso generado. ¿Cómo se hace eso?Cómo obtener un código de retorno de subproceso

Gracias, Andy

Respuesta

18

para adquirir el código de salida de un proceso en Windows puede utilizar GetExitCodeProcess().

aplicación

Ejemplo que acepta el identificador de proceso como un argumento y espera a cinco segundos para que se complete y luego adquiere su código de salida:

int main(int a_argc, char** a_argv) 
{ 
    int pid = atoi(*(a_argv + 1)); 

    HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid); 

    if (NULL != h) 
    { 
     WaitForSingleObject(h, 5000); // Change to 'INFINITE' wait if req'd 
     DWORD exit_code; 
     if (FALSE == GetExitCodeProcess(h, &exit_code)) 
     { 
      std::cerr << "GetExitCodeProcess() failure: " << 
       GetLastError() << "\n"; 
     } 
     else if (STILL_ACTIVE == exit_code) 
     { 
      std::cout << "Still running\n"; 
     } 
     else 
     { 
      std::cout << "exit code=" << exit_code << "\n"; 
     } 
     CloseHandle(h); 
    } 
    else 
    { 
     std::cerr << "OpenProcess() failure: " << GetLastError() << "\n"; 
    } 

    return 0; 
} 
+3

Gracias. Esto es lo que estaba buscando. Parece que tendré que usar CreateProcess() para comenzar esto. Esa función llena una estructura PROCESS_INFORMATION que tiene la HANDLE que necesito para usar con GetExitCodeProcess(). –

+0

Cuando haya terminado con el mango, asegúrese de cerrarlo con la función 'CloseHandle'. –

+0

@EugeneRyabtsev, gracias, olvidé agregar eso. Actualizado. – hmjd

4

Aquí es un código completo basado en http://msdn.microsoft.com/en-us/library/windows/desktop/ms682512%28v=vs.85%29.aspx y la solución de hmjd :

#include <stdio.h> 
#include <Windows.h> 

int main() 
{ 
    const size_t stringSize = 1000; 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 
    DWORD exit_code; 
    char commandLine[stringSize] = "C:\\myDir\\someExecutable.exe param1 param2"; 
    WCHAR wCommandLine[stringSize]; 
    mbstowcs (wCommandLine, commandLine, stringSize); 

    ZeroMemory(&si, sizeof(si)); 
    si.cb = sizeof(si); 
    ZeroMemory(&pi, sizeof(pi)); 

    // Start the child process. 
    if(!CreateProcess(NULL, // No module name (use command line) 
     wCommandLine, // Command line 
     NULL,   // Process handle not inheritable 
     NULL,   // Thread handle not inheritable 
     FALSE,   // Set handle inheritance to FALSE 
     0,    // No creation flags 
     NULL,   // Use parent's environment block 
     NULL,   // Use parent's starting directory 
     &si,   // Pointer to STARTUPINFO structure 
     &pi)   // Pointer to PROCESS_INFORMATION structure 
) 
    { 
     printf("CreateProcess failed (%d).\n", GetLastError()); 
     return -1; 
    } 

    // Wait until child process exits. 
    WaitForSingleObject(pi.hProcess, INFINITE); 

    GetExitCodeProcess(pi.hProcess, &exit_code); 

    printf("the execution of: \"%s\"\nreturns: %d\n", commandLine, exit_code); 

    // Close process and thread handles. 
    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 
    return 0; 
} 

(se ejecuta como aplicación de consola VS2005 en windows XP)

+0

Sería prudente agregar comillas alrededor de los 0º parámetros de la línea de comando en caso de que alguien copie el fragmento y ponga '... \ my dir \ ...' ahí. –

+0

Funciona bien como está (está probado). No se necesitan comillas adicionales, incluso si la ruta contiene espacios. Por el contrario, si se agregan las comillas alrededor de "commandLine", "CreateProcess" no funcionará. – cesargastonec

+1

http://www.verisigninc.com/en_AU/cyber-security/security-intelligence/vulnerability-reports/articles/index.xhtml?id=340 –

Cuestiones relacionadas