Tech Support > Microsoft Windows > Development Resources > Pipe and FILE handle
Pipe and FILE handle
Posted by on July 3rd, 2003



Hi,

i'm starting with Windows programing.

I've seen that i can't use popen() or _popen() in a windows based program.
I want to use it to execute an external console based program, and get the
console output.
So, i know how to create a consol based process that will use _popen(), and
i would like to create a NamedPipe to make able the main program and the
process to comunicate.

but,
i would like to connect the FILE* that is returned by the popen() and the
NamedPipe, so, i hope the main program will be able to cast the namedpipe
HANDLE to FILE* and use it like it.

Can somebody help me ?

How can i connect those two pipe together, or how can i do it by an other
way ?

thanks

jauss



Posted by Lionel Fourquaux on July 3rd, 2003


<jauss> a écrit dans le message de news:3f044bed$0$4622$626a54ce@news.free.fr...
You should probably start by reading the "Base Services" chapter in MSDN,
and the documentation for the C runtime library (in MSDN, too).

It's really _popen(): the underscore means you should not expect a standard
behaviour from this function (e.g. compared to popen() on Unix). So, be
careful if you are used to another OS: _popen() may or may not be what
you expect.

This should work.

I don't understand what you mean. Is there a reason for not calling _popen()
from the main program? Or do you want to make _popen() work with a
named pipe (and why)?

I don't understand the connection whith your previous sentence, but I can
answer that. The FILE * type defined by the C runtime is simply a wrapper
around an emulation of file descriptors, which is itself constructed from
Win32 file HANDLEs. To get the underlying handle from a FILE *, you
can use _fileno (which gives you a file descriptor), then _get_osfhandle.
To build a FILE * around a HANDLE, you can use _open_osfhandle
(which builds a file descriptor), then _fdopen.

However, you should also consider doing everything with HANDLEs,
by calling CreateProcess directly (_popen() is a wrapped around
CreateProcess). This will give you much more control on what happens
(e.g. you can redirect both the standard input and the standard output
using this method).

It would help if you could describe more precisely what you are trying to do,
and why you want to do it that way.

Hope this helps.

-- Lionel Fourquaux


Posted by Tim Robinson on July 3rd, 2003


"Lionel Fourquaux" <no.spam@invalid.nowhere> wrote in message
news:be1n9j$ljq$1@news-reader3.wanadoo.fr...
No, the _ is there because _popen is declared in one of the C standard
headers. Because it's not part of the C standard, yet it's in one of the
standard headers, it needs an _ to allow that header to conform to the C
standard.

--
Tim Robinson (MVP, Windows SDK)
http://www.themobius.co.uk/



Posted by Lionel Fourquaux on July 3rd, 2003


"Tim Robinson" <tim.at.gaat.freeserve.co.uk@invalid.com> a écrit dans le message de news:be1tjq$d6ig$1@ID-103400.news.dfncis.de...
OK. Thanks for the correction!
-- Lionel


Posted by on July 4th, 2003


ok, thanks, i'll look for that.

Exactly, i want to execute a console based program an get its standard
output into a main based windows program. I did it redirecting the stdout
into a file, and reading that file in my main program. But it's too much
slow. That's why i would like to use popen().
Using _popen() or _wpopen(), i know i can do it from a console based
program, by receving a FILE * fro the _popen(). Than, i would be able to
usit it like a file.
My probleme is that _popen() doesn't work in a windows based program (cf
MSDN).
That's why i want to create a pipe between main windows based program and my
process, and be able to use a FILE* from my main program to to read the
FILE* created by the popen in my process...

I'll look for _fileno _get_osfhandle. maybe it will help me.


thanks for your helt,

if you have any other idea, it would be most appreciated

Jauss



"Lionel Fourquaux" <no.spam@invalid.nowhere> a écrit dans le message de
news:be1n9j$ljq$1@news-reader3.wanadoo.fr...


Posted by Jugoslav Dujic on July 4th, 2003


jauss wrote:
| ok, thanks, i'll look for that.
|
| Exactly, i want to execute a console based program an get its standard
| output into a main based windows program.
| That's why i want to create a pipe between main windows based program and my
| process, and be able to use a FILE* from my main program to to read the
| FILE* created by the popen in my process...
|
| I'll look for _fileno _get_osfhandle. maybe it will help me.

This KB article is frequently referred to. It uses pure API calls, but
it explains the underlying principles well:

http://msdn.microsoft.com/library/de...llproc/base/cr
eating_a_child_process_with_redirected_input_and_o utput.asp

--
Jugoslav
___________
www.geocities.com/jdujic


Posted by Lionel Fourquaux on July 4th, 2003


<jauss> a écrit dans le message de news:3f05375b$0$13206$626a54ce@news.free.fr...
It works perfectly, but you get a new console for the subprocess, which probably
isn't what you want. Here is the way I'd do it:
* create an anonymous pipe with CreatePipe
* for multithreaded programs, you may want to enter a critical section here
(for security reasons, to avoid passing the pipe HANDLE to another child
process)
* mark the pipe input HANDLE as inheritable (using SetHandleInformation,
or DuplicateHandle if you need to support Win9x)
* call CreateProcess, specifying standard handles in STARTUPINFO,
including the pipe input for stdout, and requesting either no console, or
a hidden console window (this is probably better, since the subprocess
may somehow need a console)
* close the pipe input
* for multithreaded programs, exit the critical section
* possibly, if you want to use the C runtime file functions, build a FILE *
around the pipe output handle, using _open_osfhandle and _fdopen.

This is basically what _popen() does, except that you have full control
on the arguments passed to CreateProcess, and so you can avoid
unneeded (visible) console windows.

Hope this helps.

-- Lionel Fourquaux


Posted by Lionel Fourquaux on July 4th, 2003


<jauss> a écrit dans le message de news:3f05a246$0$13205$626a54ce@news.free.fr...
Your console process is probably using the console code page for output,
while GUI application usually work with the ansi code page. For non-ascii
characters, they usually differ. You can use MultiByteToWideChar and
WideCharToMultiByte (or equivalent C runtime function, though they will
be slightly harder to use) to convert from one encoding to the other, using
unicode (utf-16) as an intermediate form. If your GUI uses unicode characters
(which is best, IMHO), you can avoid one conversion.


Regards.

-- Lionel Fourquaux