I'm using ShellExecuteEx to execute a command in C. Is there a way to use ShellExecuteEx and capture standard in/out/err?
Note: I don't want to use CreateProcess.
I use to found the problem like you.
Suppose, You want to capture the output from STDOUT that it's generated by dir command and save the captured into out.txt.
Use text editor and type dir > out.txt and save it with mybat.bat (*.bat, don't *.txt)
In your c/c++ program, type WinExec("mybat.bat", SW_HIDE); and run your application.
Open the out.txt you will see the name of folders and files in current directory.
Also, you can run any executable files (*.exe) at the same way as follow.
xxx.exe > out.txt
I hope it can be helps you.
Sorry, my English really not good.
No. The only way to do this is to use CreatePipe and CreateProcess. See the MSDN article here
That's not possible. ShellExecute(Ex) basically executes the application in the context of the shell - so you are basically doing what explorer does.
Capturing STDIN and STDOUT is something the shell generally doesn't do, you you will have to go the CreateProcess route (which, after all, is what ShellExecute eventually calls if the file to execute is a program and the verb is 'open').
As mentioned by pilif and Bob, you need to use CreateProcess.
If you want code that wraps it all up for you, I do have a class for this exact issue at:
http://code.google.com/p/kgui/source/browse/trunk/kguithread.cpp.
The class (kGUICallThread) handles Linux, macOS and Windows versions. The code is licensed LGPL.
CreateProcess is what most people use.
You may also want to consider using _popen
http://msdn.microsoft.com/en-us/library/96ayss4b%28VS.80%29.aspx
Related
What are the main differences between the two? I'm willing to run only another EXE from my (C++) application. Are there any differences when inheriting environments, security features etc?
The main difference between CreateProcess and ShellExecute is the following: CreateProcess is more oriented on low level and ShellExec on the high user lever which see the user in explorer.
For example using of CreateProcess one can use command line which length is more as MAX_PATH. It has 32,768 characters restriction. You can also use CreateProcess to start program (if you have enough permissions) on another windows desktop like on the Logon Screen.
Another example. You can use ShellExecute to start Control Panel or open any program which existed on the computer for editing of JPG filed for example. So you works with ShellExecute close to the corresponding actions in the Windows Explorer.
The main difference is in flexibility. ShellExecute is easier to use, but doesn't have a lot of flexibility. CreateProcess is a pain to use, but lets you do anything.
Just for example, with CreateProcess, you can specify handles (pipes or files) to use for the standard input/output/error streams in the child. ShellExecute doesn't give you want way to do that.
It's probably also worth noting that although ShellExecute can be used to start an executable directly, its primary intent is to "execute" document files -- for example, tell it to "execute" a "whatever.html", and it starts up your default web browser and loads the specified HTML file into it. You can do that using CreateProcess as well, but to do it, you (normally) start by calling FindExecutable to find the program associated with the data file in question, then execute that passing your data file as a parameter.
CreateProcess returns the handle and id for the started process and it's main thread in the PROCESS_INFORMATION structure
I have a program that executes various shell commands via system() and occasionally prints to cout. I want to redirect all output coming from system() calls to a log file so they don't clutter up the normal output. Can I do this without having to append > log to all my system commands?
Looks like you can use popen
Close the stdio file descriptors (0, 1, and 2) and re-open them on whatever output device you like.
Using system is just a bad idea, period. If you use fork and execve or posix_spawn, you can easily make the necessary redirections and avoid all sorts of vulnerabilities from shell quoting issues.
If you can use a library that wrap process call. It is hard to code from posix. I use boost.process, it works fine. you can simply tell the lib how you want the output to be redirected...
my2c
How to output in buffer console output? For example I just need output of command "ipconfig -all", and want to store that information in some buffer?
You can write the output of a console application to a file (at least, in Windows), using the > parameter.
For example, for your case you'd write ipconfig -all > C:\output.txt to write the information to output.txt.
Alternatively, if you're doing it in code, you could create a process that runs ipconfig, and read the standard output using Microsoft's convoluted methods http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx, or an application framework such as Qt, which simplifies process management http://qt.nokia.com/products/ - see QProcess: http://doc.qt.nokia.com/4.3/qprocess.html#readAllStandardOutput
It seems you have an XY problem
What you really want to do is capture the output of another command. The whole "buffer" part is your first stab at an answer. It doesn't help you, and in fact it got you stuck thikning in the wrong direction.
badgerr offers some solutions, but the most common solution is popen("ifconfig -a", "r"). This doesn't return a buffer, it returns a FILE* that you can pass to fread. It's a POSIX function and available on Linux.
On Windows, you call CreateProcess and pass a STARTUPINFO structure containing dwFlags=STARTF_USESTDHANDLES, and hStdOutput=ResultOfCreatePipe.
If I have a windows console program written with c++, is it possible to retrieve that program's standard output, while the program is running? And if not, what would be the best way to rewrite the program? I know I could output to files and continuously check those files for updates. Is there another way? Is there a better way?
There are some interesting articles in Code Project:
CommandLineHelper (C#)
Redirecting an arbitrary Console's Input/Output (MFC/C++)
Universal Console Redirector (MFC/C++)
Yes, if you start the program yourself:
in CreateProcess, you pass a STARTUPINFO where you can specify handles for SDIN, STDOUT and STDERR. Note that oyu need to supply all three once you specify the STARTF_USESTDHANDLES flag.
Also, the handles need to be inheritable (otherwise, the child process can't access them), so the SECURITY_ATTRIBUTES basically need to look at least like this:
SECURITY_ATTRIBUTES secattr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
You could open handles to disk files that contain input and receive output. Alternatively, this can be Pipes that can be read / written incrementally while the console app is running.
If it is a ready console executable
you can allways redirect it output in a file like this:
c:> echo Some text > file
or
c:> program > file
If you mean this?
As your question is not exactly clear.
\\ into another program
Oh, Ok
But my first answer is also used to it.
As there is also another possibility like:
c:> program1 | program2
its make a "pipe" between console programs
program2 receive on it stdin what program1 throws to stdout
Its common old-aged Unix-way practice in console programs.
And in such way NO need to rewrite programs to specifically support it.
If you are only interested in the program's stdout, popen() makes this pretty simple:
FILE* program_output = popen("command line to start the other program");
//read from program_output as you would read a "normal" file
//...
pclose(program_output);
You'd most likely need to use pipes to achieve this, and since you're using Windows, here's a link to MSDN article with an example that seems to do exactly what you wanted.
What Windows API functions are available to execute command prompt's functionality? For example, I like to execute dir command and want to show the output in GUI without using cmd.exe in Windows.
You can start cmd /c dir S:\ome\Path from your process and grab the output. Otherwise it's not possible. But if you're not interested in particular formatting details of dir then you're probably better off just enumerating files/directories and display them.
The dir command is built into the cmd.exe, it's not a separate executable. There's no way of executing it short of running cmd.exe.
EDIT: As for the displaying of results, you need to fill in the STARTUPINFO.hStdXXX members, probably using an anonymous pipe. See this example.
For a console app you can use popen(), but things are by no means so easy from a GUI app. See http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx for one approach.
If you want a listing of files in a given folder see this question which describes how to achieve it, using windows api or a more generic boost approach.
Everything the Windows command line does is done through the Win32 APIs.
For example, with regard to "dir", FindFirstFile() and FindNextFile() will give you the contents of a directory.
For any given command, you will need to figure out which APIs/function calls are in use and then learn how to use them yourself in your own code.