CreatePipe schreiben



  • Hallo! Ich habe eine Frage zum umleiten der standardausgabe und standardeingabe.
    Hier habe ich ein Beispiel gefunden wo von stdout gelesen wird:

    CString ExecuteExternalFile(CString csExeName, CString csArguments)
    {
      CString csExecute;
      csExecute=csExeName + " " + csArguments;
    
      SECURITY_ATTRIBUTES secattr; 
      ZeroMemory(&secattr,sizeof(secattr));
      secattr.nLength = sizeof(secattr);
      secattr.bInheritHandle = TRUE;
    
      HANDLE rPipe, wPipe;
    
      //Create pipes to write and read data
    
      CreatePipe(&rPipe,&wPipe,&secattr,0);
      //
    
      STARTUPINFO sInfo; 
      ZeroMemory(&sInfo,sizeof(sInfo));
      PROCESS_INFORMATION pInfo; 
      ZeroMemory(&pInfo,sizeof(pInfo));
      sInfo.cb=sizeof(sInfo);
      sInfo.dwFlags=STARTF_USESTDHANDLES;
      sInfo.hStdInput=NULL; 
      sInfo.hStdOutput=wPipe; 
      sInfo.hStdError=wPipe;
      char command[1024]; strcpy(command,  
              csExecute.GetBuffer(csExecute.GetLength()));
    
      //Create the process here.
    
      CreateProcess(0 command,0,0,TRUE,
              NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
      CloseHandle(wPipe);
    
      //now read the output pipe here.
    
      char buf[100];
      DWORD reDword; 
      CString m_csOutput,csTemp;
      BOOL res;
      do
      {
                      res=::ReadFile(rPipe,buf,100,&reDword,0);
                      csTemp=buf;
                      m_csOutput+=csTemp.Left(reDword);
      }while(res);
    
      return m_csOutput;
    }
    

    Ich habe versucht mit WriteFile auf rPipe und wPipe zu schreiben, hat aber nicht geklappt. Hat einer eine Idee wie man es realisieren kann?


  • Mod

    Wo willst Du denn bite auf die Pipe schreiben? Der Prozess schreibt in die etsprechende offene Pipe und Du liest aus ihr. Wo ist hier in diesem Code das Problem?



  • Mit dem Code gibt es kein Problem. Ich möchte den code so verändern, dass man in das ausgeführte programm auch was schreiben kann. Braucht man da noch eine Pipe?


  • Mod

    Wenn Du damit meinst, dass das Programm etwas über stdin bekommen soll, müsstest Du auch stdin manipulieren!
    stdout und stderr haben damit ja nichts zu tun.

    Schau Dir mal ein komplettes Beispiel an:
    http://support.microsoft.com/kb/190351



  • Dieses Beispiel habe ich schon gesehen, ich finde ihn zu lang, muss man da nicht einfach 2 Pipes erzeugen, eine zum lesen und eine zum schreiben?


  • Mod

    neoexpert schrieb:

    Dieses Beispiel habe ich schon gesehen, ich finde ihn zu lang, muss man da nicht einfach 2 Pipes erzeugen, eine zum lesen und eine zum schreiben?

    Wie lang darf ein Sample sein um ein problem zu lösen?
    Ja Du musst auch eine Pipe für StdIn definieren!



  • ja
    und wenn ich ein anderes Handle als NULL dem sInfo.hStdInput zuweise, dann kann ich nicht von stdout lesen
    hier mein aktueller code.
    Es soll "cmd.exe" geöffnet werden und ein "dir\n" an das Program gesendet werden
    was mache ich denn falsch?

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    
    //---------------------------------------------------------------------------
    
    #pragma argsused
    WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
            SECURITY_ATTRIBUTES secattr;
            ZeroMemory(&secattr,sizeof(secattr));
            secattr.nLength = sizeof(secattr);
            secattr.bInheritHandle = TRUE;
    
            HANDLE rPipe, wPipe;
            HANDLE rPipe2, wPipe2;
    
            //Create pipes to write and read data
    
            CreatePipe(&rPipe,      &wPipe, &secattr,0);
            CreatePipe(&rPipe2,     &wPipe2,&secattr,0);
            //
    
            STARTUPINFO sInfo;
            ZeroMemory(&sInfo,sizeof(sInfo));
            PROCESS_INFORMATION pInfo;
            ZeroMemory(&pInfo,sizeof(pInfo));
            sInfo.cb=sizeof(sInfo);
            sInfo.dwFlags=STARTF_USESTDHANDLES;
            sInfo.hStdInput=rPipe2;
            sInfo.hStdOutput=wPipe;
            sInfo.hStdError=wPipe;
    
            //Create the process here.
    
            CreateProcess(0, "cmd.exe",0,0,TRUE,
            NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
    
            CloseHandle(wPipe);
            //now read the output pipe here.
    
            char buf[100];
            DWORD reDword;
            AnsiString m_csOutput,csTemp;
            BOOL res;
            do
            {
                    res=::ReadFile(rPipe,buf,100,&reDword,0);
                    buf[reDword]='\0';
                    csTemp=buf;
                    m_csOutput+=csTemp;
            }while(res);
            ShowMessage(m_csOutput);
            WriteFile(wPipe2,"dir\n",strlen("dir\n"),NULL,NULL);
            do
            {
                    res=::ReadFile(rPipe,buf,100,&reDword,0);
                    buf[reDword]='\0';
                    csTemp=buf;
                    m_csOutput+=csTemp;
            }while(res);
            ShowMessage(m_csOutput);
            return 0;
    }
    //---------------------------------------------------------------------------
    

  • Mod

    Es ist nicht gesagt, dass die EXE STD.IN so zweilenweise liest wie Du es erwartest. Evtl. bekommt die ja schon EOF und terminiert.

    Was hast Du denn mit dieser Umleitung auf CMD.EXE vor?
    Schreib doch einen Batch, das ist doch weitaus einfacher.


Anmelden zum Antworten