Reputation: 103
I have this code:
system("echo %username%");
I want to redirect its result to a variable, say uname
.
How can I do it?
I am aware of the WinAPI but I want to do it this way.
Upvotes: 3
Views: 3065
Reputation: 286
The quick, ugly and dirty way is to redirect the output to a file and then read that file.
system("echo %username% > someFile.txt");
A more elaborated way is to use the CreateProcess
API with the following command line: cmd.exe /c echo %username%
That API allows you to specify custom standard input and standard output. You can create a pipe for the standard output like this:
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;
And then use this pipe in the CreateProcess API. Something like this:
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
And then reads from the pipe with something like this:
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;
}
The process will be running asynchronously so you need to know when the process is terminated and do the proper cleanup. Therefore there is a bunch of details to learn here in order to make this work.
A complete example can be found here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
Upvotes: 3
Reputation: 153909
If the goal is only to get the user name, have you considered getenv
; getenv( "username" )
will return it directly.
Otherwise, if you have more that you want to do, and want the results in a file... The string you pass to system
is passed to a command interpreter, so anything you could do in a command line in cmd.exe
will work in system
: file redirection, pipe to another process, etc.
Upvotes: 0