2012-02-20 15 views
10

Jaka jest metoda uzyskania wartości zwracanej przez utworzenie podprocesu w oknach? Wygląda na to, że łatwiejsze jest użycie ShellExecute() niż w przypadku CreateProcess(), ale z dotychczasowej lektury nie wskazuję, jak sprawdzić wartość zwracaną przez zeskanowany proces. Jak to się robi?Jak uzyskać kod powrotu podprocesu?

Dzięki Andy

Odpowiedz

18

Aby uzyskać kod wyjścia procesu w systemie Windows można użyć GetExitCodeProcess().

Przykład zastosowania przyjmująca identyfikator procesu jako argumentu, i czeka na okres pięciu sekund na jej zakończenie, a następnie uzyskuje jego kodu wyjściowego:

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

dziękuję. Tego właśnie szukałem. Wygląda na to, że będę musiał użyć CreateProcess(), aby uruchomić to. Ta funkcja wypełnia strukturę PROCESS_INFORMATION, która ma RĘKĘ potrzebną do użycia z GetExitCodeProcess(). –

+0

Po zakończeniu obsługi klamki zamknij ją za pomocą funkcji 'CloseHandle'. –

+0

@EugeneRyabtsev, dziękuję, zapomniałem dodać. Zaktualizowano. – hmjd

4

Oto pełny kod oparty na http://msdn.microsoft.com/en-us/library/windows/desktop/ms682512%28v=vs.85%29.aspx i roztwór 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; 
} 

(działa jako aplikacja konsoli VS2005 w systemie Windows XP)

+0

Rozsądne byłoby dodawanie cudzysłowów wokół parametrów z wiersza polecenia w przypadku, gdyby ktoś skopiował fragment kodu, umieszczając w nim "... \ mój katalog \ ...". –

+0

Działa dobrze, jak jest (jest to sprawdzone). Żadne dodatkowe cytaty nie są potrzebne, nawet jeśli ścieżka zawiera spacje. I odwrotnie, jeśli zostaną dodane cytaty dotyczące "linii poleceń", "CreateProcess" nie będzie działać. – cesargastonec

+1

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

Powiązane problemy