Solved

How to use _popen in an MFC App

Posted on 1998-07-14
9
1,220 Views
Last Modified: 2013-11-20
Hi,

Is it possible to use _popen() in an MFC app, it always seems to fail for me!

The _popen() implementation seems to fail when it tries to do stuff (remap?) with stdin, stdout.

Is there any way to give an MFC app valid stdin and stdout without having a nasty console??

I tried _freopen()but _popen() still did not work.

Thanks

Kevin
0
Comment
Question by:KevinG
9 Comments
 
LVL 8

Expert Comment

by:trestan
ID: 1319130
Can you use fstream instead? I have used it without any problem.
0
 
LVL 2

Expert Comment

by:graber
ID: 1319131
_popen is compatable with 95 and NT.  Your outbut will have to
be redirected to some sort out device such as a dialog.

/* POPEN.C: This program uses _popen and _pclose to receive a
 * stream of text from a system process.
 */

#include <stdio.h>
#include <stdlib.h>

void main( void )
{

   char   psBuffer[128];
   FILE   *chkdsk;

        /* Run DIR so that it writes its output to a pipe. Open this
    * pipe with read text attribute so that we can read it
         * like a text file.
    */
   if( (chkdsk = _popen( "dir *.c /on /p", "rt" )) == NULL )
      exit( 1 );

   /* Read pipe until end of file. End of file indicates that
    * CHKDSK closed its standard out (probably meaning it
         * terminated).
    */
   while( !feof( chkdsk ) )
   {
      if( fgets( psBuffer, 128, chkdsk ) != NULL )
         printf( psBuffer );
   }

   /* Close pipe and print return value of CHKDSK. */
   printf( "\nProcess returned %d\n", _pclose( chkdsk ) );
}
Output
Volume in drive C is CDRIVE
 Volume Serial Number is 0E17-1702

 Directory of C:\dolphin\crt\code\pcode

05/02/94  01:05a                   805 perror.c
05/02/94  01:05a                 2,149 pipe.c
05/02/94  01:05a                   882 popen.c
05/02/94  01:05a                   206 pow.c
05/02/94  01:05a                 1,514 printf.c
05/02/94  01:05a                   454 putc.c
05/02/94  01:05a                   162 puts.c
05/02/94  01:05a                   654 putw.c
               8 File(s)          6,826 bytes
                             86,597,632 bytes free

Process returned 0
0
 
LVL 8

Expert Comment

by:trestan
ID: 1319132
Sorry for my carelessness.
The _popen() does not work under Windows application. I debug into the POPEN.C, found that the non-inheritable copy of stdhdl can not be saved, so that NULL is always returned. I do not know why. But I think there are some alternative methods to achieve your purpose. Actually the procedure will be like the POPEN do, create a console program using CreateProcess(), redirect the output from stdio to other streams. There are some functions can perform this task.
0
 

Accepted Solution

by:
racter earned 300 total points
ID: 1319133
Using popen is the wrong appoach for Windows programming...

You want to use CreateProcess, which allows you to supply
the pipes it should take in and output data to, and also
lets you set the display style for the console window that will be created for the process, in  your case you probably want it to be SW_HIDE, I'll show you below how to set this all up, basicly once you do the code below, you simply need to read the
output from the output pipe.

--------------

STARTUPINFO         sinf = {0};
PROCESS_INFORMATION pinf = {0};
SECURITY_ATTRIBUTES sa = {0};
HANDLE hPipeORead  = NULL;
HANDLE hPipeOWrite = NULL;
HANDLE hPipeIRead  = NULL;
HANDLE hPipeIWrite = NULL;

sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;

CreatePipe(&hPipeORead, &hPipeOWrite, &sa, 0);
CreatePipe(&hPipeIRead, &hPipeIWrite, &sa, 0);

sinf.cb = sizeof(sinf);
sinf.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
sinf.wShowWindow = SW_HIDE;
sinf.hStdInput = hPipeIRead;
sinf.hStdOutput = hPipeOWrite;
sinf.hStdError = hPipeOWrite;

CreateProcess(NULL, "myprogram.exe", NULL, NULL, TRUE,     NORMAL_PRIORITY_CLASS, NULL, NULL, &sinf, &pinf);


0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 8

Expert Comment

by:trestan
ID: 1319134
I have tried the code listed in the proposed answer. There are many problems to use them and finally, nothing can be read from the pipe. I am still trying to find a way to do that.
racter: I don't think you have tried to compile that codes by yourself.  
0
 

Expert Comment

by:racter
ID: 1319135
Its ment to be a code fragment, and  yes, it works, I used it to launch the MSVC compiler on the command line and then read the error messages in so I can make a pretty list of the errors.

if you want my to write every line of the code for you, thats a different problem.

Simple code to read a pipe....

DWORD total, bRead;
char byte;

PeekNamedPipe(hPipeORead, NULL, 0, NULL, &total, NULL);

if (total == 0)
   return false;

while (total--) {
    if (ReadFile(hPipeORead, &byte, 1, &bRead, NULL) == NULL)
        break;

// Do soemthing with the byte from the pipe (perhaps build a line buffer)
}
0
 

Expert Comment

by:racter
ID: 1319136
Its ment to be a code fragment, and  yes, it works, I used it to launch the MSVC compiler on the command line and then read the error messages in so I can make a pretty list of the errors.

if you want my to write every line of the code for you, thats a different problem.

Simple code to read a pipe....

DWORD total, bRead;
char byte;

PeekNamedPipe(hPipeORead, NULL, 0, NULL, &total, NULL);

if (total == 0)
   return false;

while (total--) {
    if (ReadFile(hPipeORead, &byte, 1, &bRead, NULL) == NULL)
        break;

// Do soemthing with the byte from the pipe (perhaps build a line buffer)
}
0
 
LVL 23

Expert Comment

by:chensu
ID: 1319137
These KB articles may be helpful.

How to Spawn a Console App and Redirect Standard Handles
http://support.microsoft.com/support/kb/articles/q126/6/28.asp

Redirection Issues on Windows 95 MS-DOS Apps and Batch Files
http://support.microsoft.com/support/kb/articles/q150/9/56.asp
0
 

Author Comment

by:KevinG
ID: 1319138
Hi,

I wanted to use popen() as I am under a dark cloud of UNIX Legacy source (found some K&R C in it Yesterday!) and even though I knew it wasn't the correct windows way to go I tried to be lazy and save some time, Well that back-fired!

I now intercept calls to popen() and use CreateProcess() etc., it took me a bit of time to figure out SW_HIDE though!

Kevin.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now