2010-03-31 20 views
5

Um zu testen, wie mit der Win32-API zu programmieren, schrieb ich ein Programm, das einen Prozess erstellt. Dann möchte ich überprüfen, ob mein Prozess für das neu erstellte Prozess wartet, schließen Sie den Griff und dann WaitForSingleObject erneut prüfen (der zweite Prozess für 700   ms schläft)So verwenden Sie WaitForSingleObject

Erster Prozess:

#include <iostream> 
#include <windows.h> 
#include <string> 

using namespace std; 

void main() 
{ 
    bool ret; 
    bool retwait; 

    STARTUPINFO startupinfo; 
    GetStartupInfo (&startupinfo); 

    PROCESS_INFORMATION pro2info; 

    wchar_t wcsCommandLine[] = L"D:\\betriebssystemePRA1PRO2.exe"; 

    ret = CreateProcess(NULL, wcsCommandLine, NULL, NULL, false, CREATE_NEW_CONSOLE, NULL, 
         NULL, &startupinfo, &pro2info); 

    cout<<"hProcess: "<<pro2info.hProcess<<endl; 
    cout<<"dwProcessId: "<<pro2info.dwProcessId <<endl; 

    if (retwait= WaitForSingleObject (pro2info.hProcess, INFINITE)==true) 
     cout<<"waitprocess:true"<<endl; //The process is finished 
    else 
     cout<<"waitprocess:false"<<endl; 

    CloseHandle (pro2info.hProcess);//prozesshandle schließen, "verliert connection" 

    if (retwait= WaitForSingleObject (pro2info.hProcess, INFINITE)==true) //When the process has finished 
     cout<<"waitprocess:true"<<endl; 
    else 
     cout<<"waitprocess:false"<<endl; 

    //cout<<GetLastError()<<endl; //Output the last error. 

    ExitProcess(0); 
} 

Zweite Prozess:

#include <iostream> 
#include <windows.h> 
#include <string> 

using namespace std; 

void main() 
{ 
    int b; 

    b = GetCurrentProcessId(); 

    cout << b << endl; 
    cout << "Druecken Sie Enter zum Beenden" << endl; 
    cin.get(); 
     //Wait until the user confirms 

    Sleep (700); 
    ExitProcess(0); 

    cout<<"test"; 
} 

Der erste Prozess druckt falsch, falsch; aber es sollte wahr, falsch drucken.

Anstelle der if-else-Anweisung, habe ich diese:

//switch(WaitForSingleObject (pro2info.hProcess, INFINITE)){ 
    // case WAIT_OBJECT_0: cout << "ja"; 
    //  break; 
    // case WAIT_FAILED:cout << "nein"; 
    //  break; 
    // case WAIT_TIMEOUT: 
    //  break; 
    //} 
// cout<<"waitprocess:true"<<endl;//prozess ist fertig 
//else 
// cout<<"waitprocess:false"<<endl; 

Und das scheint zu funktionieren. Was habe ich falsch mit meiner if-else Aussage gemacht?

Antwort

16

Sie wirklich Aufmerksamkeit für den Rückgabewert der API-Funktionen auf die Bedeutung zahlen müssen. Sie können eine FALSE-Rückgabe von CreateProcess() nicht ignorieren. WaitForSingleObject() kann mehrere Werte zurückgeben, es gibt 0 zurück, wenn die Wartezeit erfolgreich abgeschlossen wurde. Was bewirkt, dass Sie "falsch" drucken.

5

Nach MSDN, WaitForSingleObject wird WAIT_OBJECT_0 zurückgegeben, wenn die Wartezeit nicht abgebrochen wurde. Wenn Sie die Dokumentation überprüfen, ist der Wert von WAIT_OBJECT_0 zufällig 0x00000000L, was der Wert ist, der üblicherweise in false, nicht true konvertiert wird. Daher schlägt Ihr Vergleich fehl.

Die Förderung des Rückgabewerts von WaitForSingleObject zu einem bool ist IMHO keine gute Idee angesichts der Tatsache, dass Sie mehrere potenziell leuchtende Rückgabewerte ungleich Null erhalten, die angeben, warum die Wartezeit abgelaufen ist.

Wenn Sie den obigen Code weiterhin als boolesche Prüfung verwenden möchten, ändern Sie die Tests stattdessen in .

2

Ich denke, Sie haben Ihre Frage selbst beantwortet. Der Punkt ist, dass WaitForSingleObject nicht true oder false zurückgibt, aber WAIT_OBJECT_0 et al.

Also statt

if (retwait= WaitForSingleObject (pro2info.hProcess, INFINITE)==true) 

Sie brauchen

if (retwait= WaitForSingleObject (pro2info.hProcess, INFINITE)==WAIT_OBJECT_0)