C ++ popen команда без консоли - PullRequest
8 голосов
/ 15 августа 2011

когда я использую popen для получения выходных данных команды, скажем, dir, она выдаст консоль.

однако можно ли получить выходные данные команды без появления консоли?

Я использую Visual C ++ и хочу создать библиотеку для возврата вывода какой-либо команды, скажем, dir.

Ответы [ 3 ]

5 голосов
/ 15 августа 2011

Предполагая Windows (поскольку это единственная платформа, где это поведение является эндемическим):

CreatePipe () для создания каналов, необходимых для связи, и CreateProcess создать дочерний процесс.

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); 

Это должно более чем помочь вам сделать то, что вы хотите достичь.

2 голосов
/ 15 августа 2011

В POSIX должно быть что-то вроде этого:

//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);

Вы, конечно, должны проверять возвращаемые значения и т. Д. *

1 голос
/ 27 декабря 2016

Мне нужно было решить эту проблему для моего полноэкранного приложения Windows OpenGL, но я не смог предотвратить появление окна консоли. Вместо этого возврат фокуса после небольшой задержки, кажется, работает достаточно хорошо, чтобы не видеть его.

_popen(cmd, "wb");

Sleep(100);

ShowWindow(hWnd, SW_SHOWDEFAULT);
SetForegroundWindow(hWnd);

Обновление: это, очевидно, не работает, если программа запускается из Проводника. Работает при запуске из Visual Studio.

...