2012-02-20 9 views
10

Qual è il metodo per ottenere il valore di ritorno dalla generazione di un processo secondario all'interno di Windows? Sembra che ShellExecute() sia più semplice da utilizzare rispetto a CreateProcess(), ma dalla lettura che ho fatto fino ad ora, né viene indicato come controllare il valore restituito del processo generato. Come è fatto?Come ottenere un codice di ritorno "sottoprocesso"

Grazie, Andy

risposta

18

per acquisire il codice di uscita di un processo in Windows è possibile utilizzare GetExitCodeProcess().

applicazione

Esempio che accetta l'ID di processo come argomento e attende cinque secondi per il completamento e quindi acquisisce il codice di uscita:

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

Grazie. Questo è quello che stavo cercando. Sembra che dovrò usare CreateProcess() per iniziare questa cosa. Quella funzione riempie una struttura PROCESS_INFORMATION che ha la MANIGLIA che mi serve per l'uso con GetExitCodeProcess(). –

+0

Al termine dell'impugnatura, assicurarsi di chiuderla utilizzando la funzione 'CloseHandle'. –

+0

@EugeneRyabtsev, grazie, ho dimenticato di aggiungerlo. Aggiornato. – hmjd

4

Ecco un codice completo sede a http://msdn.microsoft.com/en-us/library/windows/desktop/ms682512%28v=vs.85%29.aspx e la soluzione di 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; 
} 

(funziona come VS2005 applicazione console in Windows XP)

+0

Sarebbe prudente aggiungere virgolette intorno ai parametri della riga di comando 0 nel caso qualcuno copi lo snippet, metti '... \ mia dir \ ...'. –

+0

Funziona bene così com'è (è provato). Non sono necessarie ulteriori citazioni, anche se il percorso contiene spazi. Al contrario, se vengono aggiunte le virgolette attorno a "commandLine", "CreateProcess" non funzionerà. – cesargastonec

+1

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

Problemi correlati