C++ popen command without console

后端 未结 4 1181
借酒劲吻你
借酒劲吻你 2020-12-20 17:20

when I use popen to get the output of a command, say dir, it will prompt out a console.

however, can I get the output of a command without the appearance of the cons

相关标签:
4条回答
  • 2020-12-20 17:24

    I needed to solve this for my full screen OpenGL Windows application, but was unable to prevent the console window popping up. Instead, taking back focus after a short delay seems to work well enough to avoid seeing it.

    _popen(cmd, "wb");
    
    Sleep(100);
    
    ShowWindow(hWnd, SW_SHOWDEFAULT);
    SetForegroundWindow(hWnd);
    

    Update: this apparently doesn't work if the program is launched from Explorer. It is working when launched from Visual Studio.

    0 讨论(0)
  • 2020-12-20 17:36

    With POSIX it should be something like this:

    //Create the pipe.
    int lsOutPipe[2];
    pipe(lsOutPipe);
    
    //Fork to two processes.
    pid_t lsPid=fork();
    
    //Check if I'm the child or parent.
    if ( 0 == lsPid )
    {//I'm the child.
      //Close the read end of the pipe.
      close(lsOutPipe[0]);
    
      //Make the pipe be my stdout.
      dup2(lsOutPipe[1],STDOUT_FILENO);
    
      //Replace my self with ls (using one of the exec() functions):
      exec("ls"....);//This never returns.  
    } // if
    
    //I'm the parent.
    //Close the read side of the pipe.
    close(lsOutPipe[1]);
    
    //Read stuff from ls:
    char buffer[1024];
    int bytesRead;
    do
    {
      bytesRead = read(emacsInPipe[0], buffer, 1024);
    
      // Do something with the read information.
      if (bytesRead > 0) printf(buffer, bytesRead);
    } while (bytesRead > 0);
    

    You should off course check return values etc...

    0 讨论(0)
  • 2020-12-20 17:41

    Assuming Windows (since this is the only platform where this behavior is endemic):

    CreatePipe() to create the pipes necessary to communicate, and CreateProcess to create the child process.

    HANDLE StdInHandles[2]; 
    HANDLE StdOutHandles[2]; 
    HANDLE StdErrHandles[2]; 
    
    CreatePipe(&StdInHandles[0], &StdInHandles[1], NULL, 4096); 
    CreatePipe(&StdOutHandles[0], &StdOutHandles[1], NULL, 4096); 
    CreatePipe(&StdErrHandles[0], &StdErrHandles[1], NULL, 4096); 
    
    
    STARTUPINFO si;   memset(&si, 0, sizeof(si));  /* zero out */ 
    
    si.dwFlags =  STARTF_USESTDHANDLES; 
    si.hStdInput = StdInHandles[0];  /* read handle */ 
    si.hStdOutput = StdOutHandles[1];  /* write handle */
    si.hStdError = StdErrHandles[1];  /* write handle */
    
    /* fix other stuff in si */
    
    PROCESS_INFORMATION pi; 
    /* fix stuff in pi */
    
    
    CreateProcess(AppName, commandline, SECURITY_ATTRIBUTES, SECURITY_ATTRIBUTES, FALSE, CREATE_NO_WINDOW |DETACHED_PROCESS, lpEnvironment, lpCurrentDirectory, &si, &pi); 
    

    This should more than get you on your way to doing what you wish to accomplish.

    0 讨论(0)
  • 2020-12-20 17:44

    Maybe something like this? This code will return the output but it has to wait for the process to finish.

    #include <iostream>
    #include <windows.h>
    
    int runCmd(const char* cmd, std::string& outOutput) {
    
        HANDLE g_hChildStd_OUT_Rd = NULL;
        HANDLE g_hChildStd_OUT_Wr = NULL;
        HANDLE g_hChildStd_ERR_Rd = NULL;
        HANDLE g_hChildStd_ERR_Wr = NULL;
    
        SECURITY_ATTRIBUTES sa;
        // Set the bInheritHandle flag so pipe handles are inherited.
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.bInheritHandle = TRUE;
        sa.lpSecurityDescriptor = NULL;
        if (!CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &sa, 0))     { return 1; } // Create a pipe for the child process's STDERR.
        if (!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) { return 1; } // Ensure the read handle to the pipe for STDERR is not inherited.
        if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0))     { return 1; } // Create a pipe for the child process's STDOUT.
        if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) { return 1; } // Ensure the read handle to the pipe for STDOUT is not inherited
    
        PROCESS_INFORMATION piProcInfo;
        STARTUPINFO siStartInfo;
        bool bSuccess = FALSE;
    
        // Set up members of the PROCESS_INFORMATION structure.
        ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
    
        // Set up members of the STARTUPINFO structure.
        // This structure specifies the STDERR and STDOUT handles for redirection.
        ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
        siStartInfo.cb = sizeof(STARTUPINFO);
        siStartInfo.hStdError  = g_hChildStd_ERR_Wr;
        siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
        siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
    
        // Create the child process.
        bSuccess = CreateProcess(
            NULL,             // program name
            (char*)cmd,       // command line
            NULL,             // process security attributes
            NULL,             // primary thread security attributes
            TRUE,             // handles are inherited
            CREATE_NO_WINDOW, // creation flags (this is what hides the window)
            NULL,             // use parent's environment
            NULL,             // use parent's current directory
            &siStartInfo,     // STARTUPINFO pointer
            &piProcInfo       // receives PROCESS_INFORMATION
        );
    
        CloseHandle(g_hChildStd_ERR_Wr);
        CloseHandle(g_hChildStd_OUT_Wr);
    
        // read output
        #define BUFSIZE 4096
        DWORD dwRead;
        CHAR chBuf[BUFSIZE];
        bool bSuccess2 = FALSE;
        for (;;) { // read stdout
            bSuccess2 = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
            if(!bSuccess2 || dwRead == 0) break;
            std::string s(chBuf, dwRead);
            outOutput += s;
        }
        dwRead = 0;
        for (;;) { // read stderr
            bSuccess2 = ReadFile(g_hChildStd_ERR_Rd, chBuf, BUFSIZE, &dwRead, NULL);
            if(!bSuccess2 || dwRead == 0) break;
            std::string s(chBuf, dwRead);
            outOutput += s;
        }
    
        // The remaining open handles are cleaned up when this process terminates.
        // To avoid resource leaks in a larger application,
        // close handles explicitly.
        return 0;
    }
    
    int main(int argc, char* argv[]) {
    
        std::string output;
        runCmd("cmd /c dir", output);
    
        std::cout << output << std::endl;
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题