2014-10-12 2 views
3

У меня есть этот код:Как перенаправить вывод функции system() в переменную?

system("echo %username%"); 

Я хочу, чтобы перенаправить результат в переменную, скажем uname.

Как я могу это сделать?

Мне известно о WinAPI, но я хочу сделать это таким образом.

+0

Вам понадобится ['труба'] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365152 (v = vs.85) .aspx) –

+0

Если вам нужно имя пользователя, подумайте об использовании собственных интерфейсов ОС. 'system' не только не защищен, но также _slow_ (новый процесс порожден и т. д.). Если вы настаиваете на повторении другого процесса, попробуйте использовать ['pipe'] (http://linux.die.net/man/2/pipe). Невозможно получить вывод команды, вызванной 'system'. – Kalrish

+0

Хорошо, тогда для системы («systeminfo»); где выход большой, как мне перенаправить его в текстовый файл? – blah

ответ

2

Быстрый, уродливый и грязный способ перенаправить вывод в файл, а затем прочитать этот файл.

system("echo %username% > someFile.txt"); 

Более подробный способ заключается в использовании CreateProcess API с помощью следующей командной строки: cmd.exe /c echo %username%

Этот API позволяет задать пользовательские стандартный ввод и стандартный вывод. Вы можете создать канал для стандартного вывода следующим образом:

HANDLE g_hChildStd_OUT_Wr = NULL; 

SECURITY_ATTRIBUTES saAttr; 

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
saAttr.bInheritHandle = TRUE; 
saAttr.lpSecurityDescriptor = NULL; 

// Create a pipe for the child process's STDOUT. 
// 
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) return -1; 

И затем используйте этот канал в API CreateProcess. Что-то вроде этого:

TCHAR szCmdline[]=TEXT("cmd.exe /c echo %username%"); 
PROCESS_INFORMATION piProcInfo; 
STARTUPINFO siStartInfo; 

// Set up members of the PROCESS_INFORMATION structure. 
// 
memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION)); 

// Set up members of the STARTUPINFO structure. 
// This structure specifies the STDIN and STDOUT handles for redirection. 
// 
memset(&siStartInfo, 0, sizeof(STARTUPINFO)); 
siStartInfo.cb = sizeof(STARTUPINFO); 
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; 
siStartInfo.dwFlags |= STARTF_USESTDHANDLES; 

// Create the child process. 
//  
bSuccess = CreateProcess(NULL, 
     szCmdline,  // command line 
     NULL,   // process security attributes 
     NULL,   // primary thread security attributes 
     TRUE,   // handles are inherited 
     0,    // creation flags 
     NULL,   // use parent's environment 
     NULL,   // use parent's current directory 
     &siStartInfo, // STARTUPINFO pointer 
     &piProcInfo); // receives PROCESS_INFORMATION 

А затем считывает из трубы с чем-то вроде этого:

DWORD dwRead, dwWritten; 
CHAR chBuf[BUFSIZE]; 
BOOL bSuccess = FALSE; 
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 

for (;;) 
{ 
     bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL); 
     if(! bSuccess || dwRead == 0) break; 
} 

Процесс будет работать асинхронно, так что вы должны знать, когда процесс завершается, и сделать правильную очистку , Поэтому здесь есть куча деталей, чтобы учиться здесь, чтобы сделать эту работу.

Полный пример можно найти здесь: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx

+0

Поскольку моя программа делает много регистрации, я предпочел бы грязный способ. Благодарю. – blah

+1

Нет ничего уродливого и грязного в использовании 'system' для вывода данных в файл. Доступные команды и то, как интерпретируется командная строка, зависят от системы, в которой вы работаете, но если это не проблема для вашего приложения, то «система» является идеальным решением. –

+0

Есть некоторые преувеличения, когда я говорю уродливые и грязные, но причина в том, что есть некоторые ограничения на этот метод, так как не все может быть красиво перенаправлено, просто добавив «> file.txt» в конце, и это связано с созданием файла которые также имеют некоторые проблемы с логистикой: назовите файл, удалите файл позже и т. д. –

0

Если цель состоит в том, чтобы только получить имя пользователя, которые вы считали getenv; getenv("username") вернет его напрямую.

В противном случае, если у вас есть больше того, что вы хотите сделать, и хотите получить результаты в файле ... Строка, которую вы передаете в system, передается командному интерпретатору, поэтому все, что вы могли бы сделать в командной строке в cmd.exe будет работать в system: перенаправление файлов, труба в другой процесс и т. д.

Смежные вопросы