Thread: Win32 Application

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    6

    Win32 Application

    I read thread "can not use popen()" of sistem. I have some problem with
    I create project Win32 application, i want to read stderr from cmd and convert to string
    but I can not because Win32 Application seem do not support method _popen()

    Could you please help me find way to deal with ?

    thanks
    Last edited by Salem; 10-24-2007 at 01:18 AM. Reason: Added link

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Use CreateProcess() with inherited stderr handles (From the parent program), MSDN has an example of this.

    Also, wrong section -- this should be in Windows programming.

  3. #3
    Registered User
    Join Date
    Oct 2007
    Posts
    6
    Quote Originally Posted by zacs7 View Post
    Use CreateProcess() with inherited stderr handles (From the parent program), MSDN has an example of this.

    Also, wrong section -- this should be in Windows programming.
    Thank you, I read at http://msdn2.microsoft.com/en-us/library/ms682499.aspx

    But I do not clear, Could you please give me some code for reading command stderr (example : java -version, ping localhost or netstat -n) put into pipe and from this pipe get all data assign to a string.
    I can do this task on Win32 Console Application but I can not on Win32 Application

    Please help me

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Why? MSDN gives you an example...

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    6
    Quote Originally Posted by zacs7 View Post
    Why? MSDN gives you an example...
    I'm sorry, I am not familiar with C code, I'm beginner

    I get this example from MSDN

    Code:
    #include <windows.h> 
    #include <tchar.h>
    #include <stdio.h> 
     
    #define BUFSIZE 4096 
     
    HANDLE hChildStdinRd, hChildStdinWr,  
       hChildStdoutRd, hChildStdoutWr, 
       hInputFile, hStdout;
     
    BOOL CreateChildProcess(VOID); 
    VOID WriteToPipe(VOID); 
    VOID ReadFromPipe(VOID); 
    VOID ErrorExit(LPSTR); 
     
    int _tmain(int argc, TCHAR *argv[]) 
    { 
       SECURITY_ATTRIBUTES saAttr; 
       BOOL fSuccess; 
     
    // Set the bInheritHandle flag so pipe handles are inherited. 
     
       saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
       saAttr.bInheritHandle = TRUE; 
       saAttr.lpSecurityDescriptor = NULL; 
    
    // Get the handle to the current STDOUT. 
     
       hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
     
    // Create a pipe for the child process's STDOUT. 
     
       if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 
          ErrorExit("Stdout pipe creation failed\n"); 
    
    // Ensure the read handle to the pipe for STDOUT is not inherited.
    
       SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);
    
    // Create a pipe for the child process's STDIN. 
     
       if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 
          ErrorExit("Stdin pipe creation failed\n"); 
    
    // Ensure the write handle to the pipe for STDIN is not inherited. 
     
       SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
     
    // Now create the child process. 
       
       fSuccess = CreateChildProcess();
       if (! fSuccess) 
          ErrorExit("Create process failed with"); 
    
    // Get a handle to the parent's input file. 
     
       if (argc == 1) 
          ErrorExit("Please specify an input file"); 
    
       printf( "\nContents of %s:\n\n", argv[1]);
    
       hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL, 
          OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); 
    
       if (hInputFile == INVALID_HANDLE_VALUE) 
          ErrorExit("CreateFile failed"); 
     
    // Write to pipe that is the standard input for a child process. 
     
       WriteToPipe(); 
     
    // Read from pipe that is the standard output for child process. 
     
       ReadFromPipe(); 
     
       return 0; 
    } 
     
    BOOL CreateChildProcess() 
    { 
       TCHAR szCmdline[]=TEXT("child");
       PROCESS_INFORMATION piProcInfo; 
       STARTUPINFO siStartInfo;
       BOOL bFuncRetn = FALSE; 
     
    // Set up members of the PROCESS_INFORMATION structure. 
     
       ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
     
    // Set up members of the STARTUPINFO structure. 
     
       ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
       siStartInfo.cb = sizeof(STARTUPINFO); 
       siStartInfo.hStdError = hChildStdoutWr;
       siStartInfo.hStdOutput = hChildStdoutWr;
       siStartInfo.hStdInput = hChildStdinRd;
       siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
     
    // Create the child process. 
        
       bFuncRetn = CreateProcess(NULL, 
          szCmdline,     // command line 
          NULL,          // process security attributes 
          NULL,          // primary thread security attributes 
          TRUE,          // handles are inherited 
          0,             // creation flags 
          NULL,          // use parent's environment 
          NULL,          // use parent's current directory 
          &siStartInfo,  // STARTUPINFO pointer 
          &piProcInfo);  // receives PROCESS_INFORMATION 
       
       if (bFuncRetn == 0) 
          ErrorExit("CreateProcess failed\n");
       else 
       {
          CloseHandle(piProcInfo.hProcess);
          CloseHandle(piProcInfo.hThread);
          return bFuncRetn;
       }
    }
     
    VOID WriteToPipe(VOID) 
    { 
       DWORD dwRead, dwWritten; 
       CHAR chBuf[BUFSIZE]; 
     
    // Read from a file and write its contents to a pipe. 
     
       for (;;) 
       { 
          if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) || 
             dwRead == 0) break; 
          if (! WriteFile(hChildStdinWr, chBuf, dwRead, 
             &dwWritten, NULL)) break; 
       } 
     
    // Close the pipe handle so the child process stops reading. 
     
       if (! CloseHandle(hChildStdinWr)) 
          ErrorExit("Close pipe failed\n"); 
    } 
     
    VOID ReadFromPipe(VOID) 
    { 
       DWORD dwRead, dwWritten; 
       CHAR chBuf[BUFSIZE]; 
    
    // Close the write end of the pipe before reading from the 
    // read end of the pipe. 
     
       if (!CloseHandle(hChildStdoutWr)) 
          ErrorExit("Closing handle failed"); 
     
    // Read output from the child process, and write to parent's STDOUT. 
     
       for (;;) 
       { 
          if( !ReadFile( hChildStdoutRd, chBuf, BUFSIZE, &dwRead, 
             NULL) || dwRead == 0) break; 
          if (! WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL)) 
             break; 
       } 
    } 
     
    VOID ErrorExit (LPSTR lpszMessage) 
    { 
       fprintf(stderr, "%s\n", lpszMessage); 
       ExitProcess(0); 
    }
    I can compile but I execute there are error here:

    LIBC.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
    Release/pipe1.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.

    I added WinMain

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    main();
    return 0;
    }

    but when execute do not any result

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You could probably replace _tmain(int argc, TCHAR **argv) with WinMain(...) and get the right result. This sample is a console app, even though it's there to show how you do things in a Windows application.

    Edit: But of course, it still won't work as a Windows app, since it's using WriteFile etc to write to the console - you still need to MODIFY the example to get it to work, instead of using WriteFile, you'd probably want to store the text your receive via ReadFile into some sort of buffer, and display that buffer as output in your app.

    Seeing this question pop up again and again, it's obvious, some class has been given the task to write a Windows app that reads the output of a console app...

    --
    Mats
    Last edited by matsp; 10-25-2007 at 02:23 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Oct 2007
    Posts
    6
    Quote Originally Posted by matsp View Post
    You could probably replace _tmain(int argc, TCHAR **argv) with WinMain(...) and get the right result. This sample is a console app, even though it's there to show how you do things in a Windows application.

    Edit: But of course, it still won't work as a Windows app, since it's using WriteFile etc to write to the console - you still need to MODIFY the example to get it to work, instead of using WriteFile, you'd probably want to store the text your receive via ReadFile into some sort of buffer, and display that buffer as output in your app.

    Seeing this question pop up again and again, it's obvious, some class has been given the task to write a Windows app that reads the output of a console app...

    --
    Mats
    I am very shy to ask everybody more, but I still can not run this code. I only study C for a week and I am not good as English, Could you please give me the best code to demo this task ? all to day I compiled, debuged, ran , create project, search google, ... this task and now my hair is stand up :-)

    one again, many thanks you all helped me

  8. #8
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    First you need to ask yourself, why do you need to read the output of a console application. If the answer is that the teacher told you to, then the solution is you need to ask the teacher for help, since he obviously didnt properly instruct you or provid eyou with the resources necessary to figure it out.

    Quote Originally Posted by miiisuuu View Post
    I'm sorry, I am not familiar with C code, I'm beginner
    Then windows programming in C is probably not an appropriate first step. Most programmers start by learning the language first, then move on to intermediate topics like redirecting I/O.
    Last edited by abachler; 10-25-2007 at 07:56 AM.

  9. #9
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    Speaking from experience, Win32 programming is completely different from console programming. In my opinion they are not related as far as layout and how the process runs.

  10. #10
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    The problem is the guy is 'new to C'. which means he needs to learn the language before he starts tackling problems specific to console versus GUI. They arent completely different, just the display stuff is different, plus win32 has more stuff that console doesnt bother with. Console programs are far easier to write, which is why beginners start with those. Once they understand the basics, then they can start learning about messaeg loops etc. Newbs tend to try to focus on every new detail presented, so its best nto to confuse them with a lot of stuff in the examples that they dont need yet. A minimal console skeleton is like 2-3 lines of code, a minimal GUI skeleton is around 20-30, most of which not even advanced programmers ever have to mess with.
    Last edited by abachler; 10-25-2007 at 08:30 AM.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, the above MS sample code isn't "beginner code". Even redirecting IO using popen itself is a bit of a stretch past "beginner", I'd say, but certainly using other techniques to redirect IO is DEFINITELY at the level beyond beginner. Just like "running" comes after "walking" when it comes to babies learning things.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Oct 2007
    Posts
    6
    Hi all,
    I read at threat can not use popen() of sistem, this is very helpfull for me, i get my goal, thanks for sistem many

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 11-08-2008, 04:48 PM
  2. win32 application wizard in microsoft visual studio
    By stanlvw in forum C++ Programming
    Replies: 4
    Last Post: 02-25-2008, 01:26 AM
  3. Adding interface to Win32 console application
    By motiz in forum Windows Programming
    Replies: 5
    Last Post: 01-03-2008, 03:17 AM
  4. Painting with Tex on a Win32 Application
    By webzest in forum C++ Programming
    Replies: 5
    Last Post: 08-16-2004, 03:04 PM
  5. How To Convert A Dos-Prompt C++ PRogram Into Win32 Application ?
    By SonicWave in forum Windows Programming
    Replies: 1
    Last Post: 09-15-2001, 11:03 AM