[Gelöst] CreateProcess/StdIn/StdOut für Kindprozess



  • Hi zusammen,

    bin mit meinem Latein am Ende... habe jetzt 3h das Inet nach einer Lösung durchsucht. Habe zwar jede Menge Code gefunden, aber keiner davon funktioniert.
    Ich möchte programmgesteuert einen postgreSQL dump ausführen und dazu pg_dump.exe mit entsprechenden Parametern aufrufen. Dazu möchte ich das zu benutzende Kennwort an den pg_dump Prozess übergeben und danach dessen Ausgaben im Parent Prozess verarbeiten. Das Starten des Kindprozesses funktioniert, aber die Übergabe des Passwortes nicht (und damit bleibt der pg_dump Prozess bei der Eingabe des Passwortes stehen).

    Hier ist der Code, wenn jemand weiß, wie ich das Problem lösen kann fände ich das super.

    void dump_db()
    {
       SECURITY_ATTRIBUTES sa;
       ::ZeroMemory( &sa, sizeof( SECURITY_ATTRIBUTES ) );
       sa.nLength = sizeof( SECURITY_ATTRIBUTES );
       sa.bInheritHandle = TRUE;
    
       // Pipe für Input erzeugen
       HANDLE ChildInputRead  = NULL;
       HANDLE ChildInputWrite = NULL;
       if( !::CreatePipe( &ChildInputRead, &ChildInputWrite, &sa, 0 ) )
       {
          return;
       } 
       // Pipe für Output erzeugen
       HANDLE ChildOutputRead  = NULL;
       HANDLE ChildOutputWrite = NULL;
       if( !::CreatePipe( &ChildOutputRead, &ChildOutputWrite, &sa, 0 ) )
       {
          ::CloseHandle( ChildInputRead );
          ::CloseHandle( ChildInputWrite );
          return;
       }
       ::SetHandleInformation( ChildInputRead  , HANDLE_FLAG_INHERIT, 0);
       ::SetHandleInformation( ChildOutputWrite, HANDLE_FLAG_INHERIT, 0);
    
       STARTUPINFO si;
       ::ZeroMemory( &si, sizeof( STARTUPINFO ) );
       si.cb         = sizeof( STARTUPINFO );
       si.dwFlags    = STARTF_USESTDHANDLES;
       si.hStdInput  = ChildInputRead;
       si.hStdOutput = ChildOutputWrite;
       si.hStdError  = ChildOutputWrite;
    
       PROCESS_INFORMATION pi;
       ::ZeroMemory( &pi, sizeof( PROCESS_INFORMATION ) );
    
       BOOL Result = ::CreateProcess( NULL, "pg_dump.exe", // Parameter für Forum entfernt
                                      NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi );
       if( Result )
       {
          // Kennwort in Input Pipe schreiben
          DWORD BytesWritten = 0;
          ::WriteFile( ChildInputWrite, "password\n", strlen( "password\n") , &BytesWritten, NULL );
    
          // Byteswritten ist hier > 0
          ::WaitForSingleObject( pi.hProcess, INFINITE );
          ::CloseHandle( pi.hThread );
          ::CloseHandle( pi.hProcess );
       }
       ::CloseHandle( ChildInputRead );
       ::CloseHandle( ChildInputWrite );
       ::CloseHandle( ChildOutputRead );
       ::CloseHandle( ChildOutputWrite );
    }
    

    Hab´ für die Handles schon alles Mögliche probiert ( GetStdHandle/CreatePipe mit und ohne DuplicateHandle ), ohne dass irgendwas funktioniert hätte.



  • Ein Schuss ins Blaue, vielleicht musst noch ein flush (weiß nicht mehr, wie die Win32 Funktion heißt) aufrufen?


  • Mod

    Wenn pg_dump das Kennwort zwingend von der Konsole list undnicht aus stdin, dann hast Du keine Chance.

    Warum arbeitest Du nicht mit eine .pgpass Datei wie empfohlen?



  • @Martin
    Genau das ist mir gestern Abend noch eingefallen. Da pg_dump die Eingabe nicht spiegelt glaube ich nicht, dass sie von stdin gelesen wird. Die .pgpass Datei wollte ich nicht verwenden, da sie Benutzernamen und Kennwort im Klartext enthält.
    Ich setzte jetzt vor dem CreateProcess Aufruf die PGPASSWORD Umgebungsvariable setze und danch wieder lösche.
    Schade, dass postgreSQL nicht sowas wie ein verschlüsselte Key Datei unterstützt, in der die Anmeldeinformationen verschlüsselt abgelegt sind. Ist vielleicht eine Anregung für das postgreSQL Entwicklerteam.



  • der Aufruf von SetHandleInformation muss so aussehen

    ::SetHandleInformation( ChildInputRead  , HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
    

    Martin Richter schrieb:

    Wenn pg_dump das Kennwort zwingend von der Konsole list undnicht aus stdin, dann hast Du keine Chance.

    Wie soll denn das gehen?


Anmelden zum Antworten