不带控制台的c++ popen命令
C++ popen command without console
当我使用popen获取命令的输出时,比如dir,它会提示出一个控制台。
但是,我可以在没有控制台的情况下获得命令的输出吗?我正在使用Visual c++,并希望创建一个库来返回某些命令的输出,例如,dir.
假设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);
这应该不仅仅是让你走在你想完成的事情的路上。
也许是这样的?此代码将返回输出,但它必须等待进程完成。
#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;
}
对于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);
我需要为我的全屏OpenGL Windows应用程序解决这个问题,但无法阻止控制台窗口弹出。相反,在短暂的延迟后重新集中注意力似乎足以避免看到它。
_popen(cmd, "wb");
Sleep(100);
ShowWindow(hWnd, SW_SHOWDEFAULT);
SetForegroundWindow(hWnd);
更新:如果程序从资源管理器启动,这显然不起作用。
相关文章:
- 从命令行c++发送文本文件名
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 使用QProcess执行命令,并将结果存储在QStringList中
- 数组长度,为什么从命令行获取时不能使用它?
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 自动"yes"到 Popen SSH 命令
- popen() 将执行命令的输出写入 cout
- 为什么返回的 FILE* 在 popen() 中的命令失败时保留数据
- 使用popen执行命令
- 在C++中使用popen执行perl命令时出错
- 命令参数不会传递给 popen 中的 /bin/sh
- 如何在 C 系统 / popen 命令中通过另一个C++程序连续输入
- 在Mac上用汉字命令调用popen()
- 不带控制台的c++ popen命令
- 在运行命令时,popen的时间间隔是多少,以及如何逐行捕获输出
- 执行命令并获得输出:popen和pclose undefined
- 从popen执行命令shell并设置其他命令shell
- popen telnet中的子命令