CreateProcess: ganzer Prozess wird mit CloseHandle geschlossen



  • Mein Programm soll eine Eingabeaufforderung für diskpart darstellen.
    Der Prozess diskpart.exe wird in einem eigenen Thread erzeugt, sodass er parallel zu meinem Hauptprgramm läuft.
    Bis Zeile 8 der Sendefunktion bleibt der diskpart Prozess gestartet.
    Anschließend wird er geschlossen, was ich jedoch nicht möchte.

    Es muss doch möglich sein, dass ich dem Prozess mit der data Variable z.B. "select disk 0" und anschließend beim zweiten Mal "detail disk" übergebe.
    Dies funktioniert jedoch nicht, da nach "select disk 0" der diskpart Prozess geschlossen wird und bei jedem weiteren Befehl "StdInWr CloseHandle" als Fehler ausgegeben wird.

    Globale Variablen

    HANDLE g_hChildStd_IN_Rd = NULL;
    HANDLE g_hChildStd_IN_Wr = NULL;
    HANDLE g_hChildStd_OUT_Rd = NULL;
    HANDLE g_hChildStd_OUT_Wr = NULL;
    HANDLE g_hInputFile = NULL;
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFOA siStartInfo;
    BOOL bSuccess = FALSE;
    SECURITY_ATTRIBUTES saAttr;
    

    Prozessfunktion:

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
        saAttr.bInheritHandle = TRUE;
        saAttr.lpSecurityDescriptor = NULL;
     // Create a pipe for the child process's STDOUT.
        if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
           ErrorExit("StdoutRd CreatePipe");
    
     // Ensure the read handle to the pipe for STDOUT is not inherited.
        if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
           ErrorExit("Stdout SetHandleInformation");
    
     // Create a pipe for the child process's STDIN.
        if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
           ErrorExit("Stdin CreatePipe");
    
     // Ensure the write handle to the pipe for STDIN is not inherited.
        if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
           ErrorExit("Stdin SetHandleInformation");
    
     // Set up members of the PROCESS_INFORMATION structure.
        ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
    
     // Set up members of the STARTUPINFO structure.
     // This structure specifies the STDIN and STDOUT handles for redirection.
    
        ZeroMemory( &siStartInfo, sizeof(STARTUPINFOA) );
        siStartInfo.cb = sizeof(STARTUPINFOA);
        siStartInfo.hStdError = g_hChildStd_OUT_Wr;
        siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
        siStartInfo.hStdInput = g_hChildStd_IN_Rd;
        siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
    
     // Create the child process.
        bSuccess = CreateProcessA(NULL,
           "diskpart.exe",     // command line
           NULL,          // process security attributes
           NULL,          // primary thread security attributes
           TRUE,          // handles are inherited
           CREATE_NO_WINDOW,             // creation flags
           NULL,          // use parent's environment
           NULL,          // use parent's current directory
           &siStartInfo,  // STARTUPINFO pointer
           &piProcInfo);  // receives PROCESS_INFORMATION
        WaitForSingleObject(piProcInfo.hProcess, INFINITE);
        // If an error occurs, exit the application.
        if ( ! bSuccess )
           ErrorExit("CreateProcess");
        else
        {
        // Close handles to the child process and its primary thread.
        // Some applications might keep these handles to monitor the status
        // of the child process, for example.
        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);
        }
    

    Sendefunktion:

    DWORD dwRead, dwWritten;
        char chBuf[BUFSIZE];
        BOOL bSuccess = FALSE;
    
        strcpy(chBuf,data.toUtf8());
        bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, data.length(), &dwWritten, NULL);
    
        if ( ! CloseHandle(g_hChildStd_IN_Wr) )
            ErrorExit("StdInWr CloseHandle");
    
        HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        if (!CloseHandle(g_hChildStd_OUT_Wr))
            ErrorExit("StdOutWr CloseHandle");
        QString var;
        for (;;)
        {
            bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
            if( ! bSuccess || dwRead == 0 ) break;
            var.append(QString(chBuf).left(dwRead));
        }
         ui->textEdit2->append(var);
    

    Bitte fragt jetzt nicht nach dem Sinn des Programms 🙂

    Ich würde mich sehr über eine Antwort freuen.

    Gruß
    paste2k



  • Dieser Thread wurde von Moderator/in akari aus dem Forum VCL (C++ Builder) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Vermutlich stellt diskpart fest, dass es nicht mit einer Console verbunden ist, und führt deswegen den Befehl nicht aus...
    Verwende doch /s!



  • Der erste Befehl, den ich an meinen Prozess sende, wird ja ausgeführt und ich bekomme die Ausgabe zurück.
    Die Zeile CloseHandle(g_hChildStd_IN_Wr) in meinem Code bewirkt aber dann irgendwie ein Schließen der diskpart.exe.

    Ich denke, das hängt evtl. mit den Parametern von SetHandleInformation (in der Prozessfunktion) zusammen.
    Wenn ich HANDLE_FLAG_INHERIT durch HANDLE_FLAG_PROTECT_FROM_CLOSE austausche, dann hängt jedoch das ganze Programm 😞



  • Warum schliesst Du ein Handle, den Du noch brauchst?



  • Ich habe den Code von dem Microsoft Beispiel (http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx) abgeleitet.

    Mir ist auch schleierhaft, weshalb das CloseHandle hier in meinem Programm noch benötigt wird.
    Aber wenn ich den CloseHandle(g_hChildStd_OUT_Wr) oder CloseHandle(g_hChildStd_IN_Wr) Aufruf weglasse oder an eine andere Stelle setze, dann hängt sich mein Programm auf 😞


Anmelden zum Antworten