Passing an input to the process created by CreateProcess() - c++

like in the title I was wondering whether is it possible to pass an input by use of redirection operators in CreateProcess(). I tried something like the following:
CreateProcess(NULL, "%ComSpec% /c c:\\somebatch.bat", NULL, NULL, ...);
where somebatch.bat contained c:\app.exe < c:\input.txt and it didn't pass the input, just launched the app.exe. On the output it said that:
c:\working_directory> c:\app.exe < c:\input.txt
c:\working_directory>Not enough storage is available to process this command.
(messing with irpcstack didn't help)
Are you guys aware of any magic trick that would allow me to do what I want without messing with the hStdInput pipe, which saying frankly I wanted to avoid. Cheers.

It has been a while since I have done this, but you have to set hStdInput member in the STARTUPINFO struct passed in as the next to last argument of CreateProcess. I'm pretty sure that there is no other good way to do this. Using hStdInput is pretty easy, open the file that you want to use as input, set hStdInput to the file handle, create the process, and close the handle.
You might be able to open the input file, duplicate the handle into the current processes standard input, and then create the process with bInheritHandles set to TRUE. Then your program will simply receive the file contents via stdin. I've never tried this in Windows, but it is common practice on UNIX based platforms.
As for running a batch file, read the comments in the MSDN entry for CreateProcess. I think that you have the arguments messed up.

Is there any reason you need CreateProcess?
The system function uses the default shell (so you wouldn't need to put in %ComSpec%) which means that redirection would work fine. It's also easier to use and more portable. If you're just going to wait for the process to finish, consider using system instead.

Related

How can I send a chain of characters to a cmd.exe from c++?

I tried with findwindow and sendmessage, but, with sendmessage I only can send message for the GUI. Help!!!!!
Try to use the keybd_event function. It's not very friendly so if you want to use it for complex tasks you may take a look to this library on CodeProject that emulates the well-known SendKey command for VBScript/.NET.
I think that best way to start command line process using CreateProcess function that takes STARTUPINFO structure with input / output handles specified.
When cmd process is already started use SendInput. But IMHO this way is less reliable.

Communication with a script from a C++ program

I have a c++ program (very complicated, and lengthy both in code and execution time).
Once in a while this program stops and calls a user-specified shell script.
Before calling the script, my program creates a .out file with current data. I call the script via system() command. The script then reads the .out file, and creates its own script.out file and exits.
Then the system() function call ends, and my program reads and parses the script.out file.
Question: is there a better way to execute communication between my c++ program and a random shell script?
My intent is to have full communication between the two. Script could virtually "ask" the program "What data do you have right now?" and the program would reply with some strict convention. Then the script could say "Add this data...", or "delete all your previous data" etc.etc.
The reason I need this is because the shell script tells the program to modify its data. The exact data that was put in the original .out file. So after the modification is done -- the actual data held by the program does not correspond to the data written in the .out file.
Thanks!
P.S.
I swear I've searched around, but everyone suggests an intermediate file.
There are certainly ways to do that without intermediate files. The most common approach is to use command line arguments for input, and pipes for standard output; others also use pipes for input. The most straight-forward alternative to system then is to use popen.
On a unix-like system? Perhaps pipe (2) will work for you?
From the man page (Mac OS X 10.5 version):
SYNOPSIS
#include <unistd.h>
int pipe(int fildes[2]);
DESCRIPTION
The pipe() function creates a pipe (an object that allows unidirectional
data flow) and allocates a pair of file descriptors. The first descrip-
tor connects to the read end of the pipe; the second connects to the
write end.
You will, of course, have to follow the creation of the pipes with a fork and exec pair. Probably this has already been answered in detail, and now you know what to search on...
It's been a while since I did this, but:
In the main process, before forking the sub-process you call pipe twice. Now you have two pipes and control both ends of both of them.
You fork.
The main process will read from one pipe and write from the other. It doesn't matter which is which, but you need to be clear about this.
The child process will call one of the exec family of function to replace it's image with that of the shell you want to run but first you will use dup2 to replace it's standard input and output with the ends of the two pipes (again, this is where you need to be clear about which pipe is which).
At his point you have two processes, the main process can send things into one pipe ad they will be received on the standard input of the script, and anything the script writes to it's standard output will be sent up the other pipe to the controlling process. So they take turns, just like interacting with the shell.
You can use pipes or (maybe more convenient) sockets - for example frontends to gdb, or expect do that. It would require changes to your shell scripts, and switching from system() to more low-level fork() and exec().
It's rather complicated so please, be more specific about your environment and what you need to clarify.
You are asking the question on Interprocess Communication (IPC).
There are a lot of ways to do that. You can do a simply search and Internet will return you most answers.
If I am not wrong, Google chrome uses a technique called Named Pipe.
Anyway, I think the most "portable way" is probably a file. But if you know you are working on which operating system, you can definitely use most of the IPC techniques.

How to output in buffer console output?

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.

Is it possible to get the output of a program while it's running?

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.

Crossplatform Bidirectional IPC

I have a project that I thought was going to be relatively easy, but is turning out to be more of a pain that I had hoped. First, most of the code I'm interacting with is legacy code that I don't have control over, so I can't do big paradigm changes.
Here's a simplified explanation of what I need to do: Say I have a large number of simple programs that read from stdin and write to stdout. (These I can't touch). Basically, input to stdin is a command like "Set temperature to 100" or something like that. And the output is an event "Temperature has been set to 100" or "Temperature has fallen below setpoint".
What I'd like to do is write an application that can start a bunch of these simple programs, watch for events and then send commands to them as necessary. My initial plan was to something like popen, but I need a bidrectional popen to get both read and write pipes. I hacked something together that I call popen2 where I pass it the command to run and two FILE* that get filled with the read and write stream. Then all I need to do is write a simple loop that reads from each of the stdouts from each of the processes, does the logic that it needs and then writes commands back to the proper process.
Here's some pseudocode
FILE *p1read, *p1write;
FILE *p2read, *p2write;
FILE *p3read, *p3write;
//start each command, attach to stdin and stdout
popen2("process1",&p1read,&p1write);
popen2("process2",&p2read,&p2write);
popen2("process3",&p3read,&p3write);
while (1)
{
//read status from each process
char status1[1024];
char status2[1024];
char status3[1024];
fread(status1,1024,p1read);
fread(status2,1024,p2read);
fread(status3,1024,p3read);
char command1[1024];
char command2[1024];
char command3[1024];
//do some logic here
//write command back to each process
fwrite(command1,p1write);
fwrite(command2,p2write);
fwrite(command3,p3write);
}
The real program is more complicated where it peeks in the stream to see if anything is waiting, if not, it will skip that process, likewise if it doesn't need to send a command to a certain process it doesn't. But this code gives the basic idea.
Now this works great on my UNIX box and even pretty good on a Windows XP box with cygwin. However, now I need to get it to work on Win32 natively.
The hard part is that my popen2 uses fork() and execl() to start the process and assign the streams to stdin and stdout of the child processes. Is there a clean way I can do this in windows? Basically, I'd like to create a popen2 that works in windows the same way as my unix version. This way the only windows specific code would be in that function and I could get away with everything else working the same way.
Any Ideas?
Thanks!
On Windows, you invoke CreatePipe first (similar to pipe(2)), then CreateProcess. The trick here is that CreateProcess has a parameter where you can pass stdin, stdout, stderr of the newly-created process.
Notice that when you use stdio, you need to do fdopen to create the file object afterwards, which expects file numbers. In the Microsoft CRT, file numbers are different from OS file handles. So to return the other end of CreatePipe to the caller, you first need _open_osfhandle to get a CRT file number, and then fdopen on that.
If you want to see working code, check out _PyPopen in
http://svn.python.org/view/python/trunk/Modules/posixmodule.c?view=markup
I think you've made a very good start to your problem by using the popen2() function to abstract away the cross-platform issues. I was expecting to come and suggest 'sockets', but I'm sure that's not relevant after reading the question. You could use sockets instead of pipes - it would be hidden in the popen2() function.
I am 99% sure you can implement the required functionality on Windows, using Windows APIs. What I cannot do is point you to the right functions reliably. However, you should be aware the Microsoft has most of the POSIX-like API calls available, but the name is prefixed with '_'. There are also native API calls that achieve the effects of fork and exec.
Your comments suggest that you are aware of issues with availability of data and possible deadlocks - be cautious.