views:

549

answers:

6

I've written a small console application to wrap a third-party DLL that has issues. I am calling it from a GUI application using _popen, and just want to read a value from the console program's standard output. In doing so, an undesirable console window is briefly displayed.

I am aware that this can be avoided by using a certain STARTUPINFO configuration with CreateProcess. However, I would prefer to put the fix in the console application and still use _popen. Creating the child process using the windows subsystem (i.e. WinMain instead of main) does not make the console window go away. Apparently, a console is allocated by the operating system to facilitate the _popen communication.

Note that the third-party DLL is unstable, but necessary to interface with proprietary hardware. Therefore, any approach the loads the DLL in the GUI applications memory space is unacceptable.

A: 

Instead of a console app you could wrap it in a windows app that draws itself off screen e.g.

in constructor:

Location = new Point(-1000, -1000);

You can also set the main Form to not appear in the task bar and even get rid of its control box for good measure.

Hacky i know, but should work.

Paul Sasik
Don't I still have to open a console window (with AllocConsole) for the parent process to be able to read stdout?
Judge Maygarden
i don't think stdout is solely for consoles. There must be a way to get stdout for a windowing app. But that's another question...
Paul Sasik
Stdout is solely for consoles. You'd have to make a console just to get a stdout handle.
Steven Sudit
-1000, -1000 could be a valid point on a multi-monitor system. BTW what are Location and Points - not Win32?
Aardvark
@Steven: The default for Stdin and Stdout is for console but they can be redirected to any application. Here's one working example: http://www.codeproject.com/KB/dialog/quickwin.aspx?msg=250407
Paul Sasik
@psasik: From the point of view of the console app, it's running in a console. However, rather than a console of its own creation, it's one that it got from its caller.
Steven Sudit
+4  A: 

It is possible as I've answered it in a previous question

Indeera
I think you have.
Steven Sudit
+1  A: 

1) I support the idea of launching it with STARTUPINFO set to hide the window. This is SOP on Windows, so it'll work better than trying to impose Unix SOP. Moreover, you may well want to see the output when testing it in isolation.

2) Or you can make a GUI app that doesn't ever show a window. It amounts to a console app without a console.

edit

The link Indeera posted shows how to do the second option.

edit

Ok, if all you want is to send information to the parent, the simplest way is to write a file. One way to keep this orderly is to have the parent pass a unique filename as a command line parameter, which the child writes to. The parent can monitor the file and act on its contents.

There are many alternativers. The closest to the two approaches discussed so far would be named pipes, but you could also use various forms of IPC, including socket-based ones.

What you can't do, however, is access stdin/stdout/stderr without a console. You can launch with a hidden console, but it has to actually have one.

edit

Does lua allow running the executable directly, instead of through cmd.exe?

Steven Sudit
I'm looking at the Lua sources and it is just calling _popen.
Judge Maygarden
I'm sorry, I wasn't clear. It's called _popen to open the pipe, but I was trying to understand what it's calling to spawn the process.
Steven Sudit
Actually, _popen spawns the process too. From MSDN: "Creates a pipe and executes a command." See http://msdn.microsoft.com/en-us/library/96ayss4b(VS.80).aspx
Judge Maygarden
I'm running Vista, but from what I'm reading this usage of _popen from a GUI application used to break completely.
Judge Maygarden
Does it allow you to control how the process is started?
Steven Sudit
_popen does not, but it looks like I'll have to go with a more heavy-weight solution. I think I'll just spawn the processes with STARTUPINFO and CreateProcess and send the data back through a named pipe. That's so much more work and I'm extremely lazy! :(
Judge Maygarden
I would just say that you are interested in efficient development. Oh, and since you have a Unix background, let me remind you that named pipes under Windows aren't exactly the same thing as their Unix namesakes. For a quick reference, check out http://en.wikipedia.org/wiki/Named_pipe#Named_pipes_in_Windows
Steven Sudit
A: 

I don't think you can use stdin/stdout without it starting up the console. What you can do though, is write the wrapper app as a GUI app that doesn't show any window (just switch main() to winmain()) and then use some type of IPC mechanism like a socket or shared memory.

Rob K
I would suggest passing the commands it needs on the command line when launching it, if possible.
Steven Sudit
@Steven: I think he needs 2-way communication
Aardvark
No, I just need communication from to the child process to the parent.
Judge Maygarden
A: 

I'm not sure, but this might be useful: http://stackoverflow.com/questions/597818/gcc-c-how-to-hide-console-window

anon
+1  A: 

To communicate between a parent GUI application and a hidden child console application reference the following MSDN articles:

Judge Maygarden