2011-08-15 166 views
8

當我使用popen獲取命令的輸出時,比如說dir,它會提示出一個控制檯。沒有控制檯的C++ popen命令

但是,我可以在沒有控制檯外觀的情況下獲得命令的輸出嗎?

我正在使用Visual C++,並希望使庫返回某些命令的輸出,比如dir。

+4

你使用的是什麼平臺/工具鏈? – Flexo

+2

你在使用什麼操作系統?這不會在適當的操作系統中發生,例如Linux,但也許你正在使用例如在Windows下的cygwin? –

+0

如果這是Windows(而且我100%確定它是這樣的,就像我多年來一直爭取這麼多次一樣),唯一可靠的方法就是使用CreateProcess。大多數其他庫跳過必要的標誌以防止打開子控制檯。 –

回答

2

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

你應該關閉過程檢查返回值等等

+0

什麼是管道? Visual Studio強調了這個詞。 – user883434

+0

是否應該包含任何庫? – user883434

+0

還有幾個變量,我不知道他們的類型... – user883434

5

假設的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

對不起。什麼是必要的圖書館? – user883434

+0

指向MSDN文檔的鏈接準確地告訴你要包含哪些頭文件和庫,但本例中的庫是WIN32 kernel32庫。 –

+0

有用,但我不得不使用不同的標誌,使其工作。看到這個:http://stackoverflow.com/a/16953192/453673 – Nav

1

我需要爲我的全屏OpenGL Windows應用程序解決這個問題,但無法防止控制檯窗口彈出。取而代之的是,在短暫的延遲後重新獲得焦點似乎足以避免看到它。

_popen(cmd, "wb"); 

Sleep(100); 

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

更新:如果程序從資源管理器啓動,這顯然不起作用。它從Visual Studio啓動時正在工作。