none
Force a process to write stdout RRS feed

  • Question

  • Hi, currently i am interoping a command line application with a automation testing application, and i am facing problems with redirection. The application itself is a closed debugger for a custom architecture and i do not have it's the source code. The redirection code is the most commonly used.

    if launched from cmd it's shows data on the screen properly but it's not writing to stdout when redirected, only after the process terminates. My testing application needs to fetch and modify data on the fly so i need immediate data.

    This is the only process i've ever seen with this kind of behavior, since it behaves normally when not redirected i believe the data is stuck somewhere. Can i flush it? Why does it happen?

     

    EDIT: I've managed to get the data injecting code to the process and reading the console buffer as a whole but it's causing a lot of synchronization errors and loss of data so i want to avoid it.

     

    Thanks,

     

    Caian


    Sunday, August 21, 2011 7:50 PM

Answers

  •  

    Hi,

     

    I did a test for redirection standard input&output.

     

    Here is the application A:

    static void Main(string[] args)

            {

                string x = Console.ReadLine();

     

                for (int i = 0; i < 16; i++)

                {

                    Console.WriteLine("line "+(i+1) + x);

                }

            }

    Here is the application B:

     Process fasm = new Process();

                fasm.StartInfo.FileName = "RedirectionA.exe";

                fasm.StartInfo.UseShellExecute = false;

                fasm.StartInfo.CreateNoWindow = true;

                fasm.StartInfo.RedirectStandardInput = true;

                fasm.StartInfo.RedirectStandardOutput = true;

                fasm.Start();

     

                fasm.StandardInput.WriteLine("TEST FROM APP A");

     

                string[] result = new string[16];

                for (int i = 0; i < 16; i++)

                    result[i] = fasm.StandardOutput.ReadLine();

    The test application B can get output correctly from application A.

    I think the issue is related to the application that you do not have source code of.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Paul Zhou Monday, August 29, 2011 6:08 AM
    Friday, August 26, 2011 5:26 AM
  • That's what I expected you would see.  I have seen that behavior before in another thread, but the OP gave up on writing to a log.  He seemed to be in a hurry and bailed on the thread, never replying back.

    So, what is it that occurs when the writer object instance is closed that does not occur when the writer instance is merely flushed?  You cannot be sure of the exact type that is used.  The instance is supplied by the Framework.  I think the underlying stream is the key to what is occurring.  Thanks, you've given me a brain teaser.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/




    • Marked as answer by Paul Zhou Monday, August 29, 2011 6:07 AM
    Sunday, August 28, 2011 4:26 PM
  • Ok, giving another chance to NamePipeServerStream, this time i'm ignoring the ProcessStartupInfo.Redirect stuff, here's the results:

    *Note, i'm launching fm.exe from cmd itself not from my application.

     

    -Launching: fm.exe < mypipein, where mypipein has zero-size buffer and write-through flag, and everything works ok! Data is flushed and the result is shown in the console on the fly.

     

    -Launching: fm.exe > mypipeout, where mypipeout has default-size buffer and write-through flag, data is also flushed on the fly as soon as i input it in the console.

     

    -Launching: fm.exe < mypipein > mypipeout, same configurations as above... failure, reader hangs.

     

    This is quite redundant because Process use pipes for redirection but i'm starting to fear that the problem goes beyond pipes, but the way Windows manages the whole stuff, this would explain the behavior that Rudy suggested... and perhaps there's no workaround.

    • Marked as answer by Paul Zhou Monday, August 29, 2011 6:07 AM
    Sunday, August 28, 2011 10:49 PM

All replies

  • The output is redirected to a stream.  Sometimes you will not see the redirected output until the underlying stream is closed, which flushes it. 

    Can you post code the reproduces the issue?  We could use a sample console application that writes Hello World once per second as the test application.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/


    Sunday, August 21, 2011 8:03 PM
  • Process fasm = new Process();
    fasm.StartInfo.FileName = "bin\\fm.exe";
    fasm.StartInfo.Arguments = "-l test.hex";
    fasm.StartInfo.UseShellExecute = false;
    fasm.StartInfo.CreateNoWindow = true;
    fasm.StartInfo.RedirectStandardInput = true;
    fasm.StartInfo.RedirectStandardOutput = true;
    fasm.StartInfo.RedirectStandardError = true;
    fasm.Start();
    
    //Later on the program:
    
    // Dump memory
    fasm.StandardInput.WriteLine("d 0h 100h");
    
    // This will produce 16 lines of data
    string[] data = new string[16];
    for (int i = 0; i < 16; i++)
     data[i] = fasm.StandardOutput.ReadLine();
    

     

     

    As i said, a common redirection code, it works on anything i've tested, except this specific console program. Running on cmd it produces exact 16 lines of memory dump but when redirected it hangs on any read attempt, can be a ReadToEnd, Read specific bytes or Read the whole line.



    Sunday, August 21, 2011 8:56 PM
  • I still think the underlying stream is the key to understanding redirection.  Try calling Flush on the fasm.StreamWriter object.

    I also know that redirection to the underlying stream will not occur until an CR/LF is output by the console application.  For example, a series of calls to Console.Write should not send anything to the stream until a call is made Console.WriteLine to end the line. 

    Hope this helps.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Sunday, August 21, 2011 9:18 PM
  • Flushing both in and out does not helped, tried to Peek output and it hanged too...

     

    Is it possible that the console application is writing to the console buffer directly without using printf?

     


    Sunday, August 21, 2011 9:27 PM
  • Hmmph.  I dunno.  What about the StreamWriter's AutoFlush property?   Same no results, I would expect.  Set that property before you call Start.
    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Sunday, August 21, 2011 9:33 PM
  • Hum, nothing, i had to put it after start because the an exception was raised otherwise.
    Sunday, August 21, 2011 9:37 PM
  • Hi,

    For redirect standard I/O, you can refer to the link below:

    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/deb1a53c-9307-45e1-b99c-64bb07b16e0e


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, August 25, 2011 7:10 AM
  • As you can clearly see in the previous posts, the problems extends beyond the conventional ( and already used ) method of redirecting stdout.

    Thursday, August 25, 2011 3:46 PM
  •  

    Hi,

     

    I did a test for redirection standard input&output.

     

    Here is the application A:

    static void Main(string[] args)

            {

                string x = Console.ReadLine();

     

                for (int i = 0; i < 16; i++)

                {

                    Console.WriteLine("line "+(i+1) + x);

                }

            }

    Here is the application B:

     Process fasm = new Process();

                fasm.StartInfo.FileName = "RedirectionA.exe";

                fasm.StartInfo.UseShellExecute = false;

                fasm.StartInfo.CreateNoWindow = true;

                fasm.StartInfo.RedirectStandardInput = true;

                fasm.StartInfo.RedirectStandardOutput = true;

                fasm.Start();

     

                fasm.StandardInput.WriteLine("TEST FROM APP A");

     

                string[] result = new string[16];

                for (int i = 0; i < 16; i++)

                    result[i] = fasm.StandardOutput.ReadLine();

    The test application B can get output correctly from application A.

    I think the issue is related to the application that you do not have source code of.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Paul Zhou Monday, August 29, 2011 6:08 AM
    Friday, August 26, 2011 5:26 AM
  • Yes, i think the "fm.exe" is writing (if possible) directly to the console buffer so the data is not being flushed until program termination.
    Friday, August 26, 2011 9:10 AM
  • We could use a sample console application that writes Hello World once per second as the test application.

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

    us zip code

    Friday, August 26, 2011 4:40 PM
  • Since your kicking off a seperate process this thread http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/2c8946c4-90c9-42a0-8ea8-b24b738b2ec1/, might help you with how to get the information you're looking for.
    Friday, August 26, 2011 8:49 PM
  • Yes, i think the "fm.exe" is writing (if possible) directly to the console buffer so the data is not being flushed until program termination.


    I agree.  That is what I was suggesting above.  You could probably test that idea by closing the Writer instance.  It would be difficult if not impossible to re-initialize a new one. 

    Does fm.exe write complete lines or just partial lines of text?  How often does it output NewLine characters?

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Friday, August 26, 2011 11:17 PM
  • Yes, i think the "fm.exe" is writing (if possible) directly to the console buffer so the data is not being flushed until program termination.


    I agree.  That is what I was suggesting above.  You could probably test that idea by closing the Writer instance.  It would be difficult if not impossible to re-initialize a new one. 

    Does fm.exe write complete lines or just partial lines of text?  How often does it output NewLine characters?

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Interesting, closing the writer now allows reading from stdout. I can't really tell if the lines are partial, i believe they are complete, in any case there are about 10 to 20 output lines printed per input command.
    Saturday, August 27, 2011 12:00 AM
  • That's what I expected you would see.  I have seen that behavior before in another thread, but the OP gave up on writing to a log.  He seemed to be in a hurry and bailed on the thread, never replying back.

    So, what is it that occurs when the writer object instance is closed that does not occur when the writer instance is merely flushed?  You cannot be sure of the exact type that is used.  The instance is supplied by the Framework.  I think the underlying stream is the key to what is occurring.  Thanks, you've given me a brain teaser.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/




    • Marked as answer by Paul Zhou Monday, August 29, 2011 6:07 AM
    Sunday, August 28, 2011 4:26 PM
  • Thanks Rudy, one thing that i've tried also is opening the pipe myself using a NamedPipeServerStream and it had the same behavior. Perhaps if i create the pipe using native C++? I'll test it out...
    Sunday, August 28, 2011 6:20 PM
  • Is it possible the application is writing to stderr or stdwrn?

    One of the posts on the thread I pointed out earlier talks about keeping the event handlers open for a second after the process exits.

    Have you tried to sleep for a second, after the process exits to see if the buffers all flush then?

    Sunday, August 28, 2011 7:43 PM
  • Yes, all the data is flushed to stdout immediately after the process exits.
    Sunday, August 28, 2011 8:12 PM
  • Yes, all the data is flushed to stdout immediately after the process exits.

    ...which means the writer and its' stream are Disposed.
    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Sunday, August 28, 2011 8:45 PM
  • Ok, giving another chance to NamePipeServerStream, this time i'm ignoring the ProcessStartupInfo.Redirect stuff, here's the results:

    *Note, i'm launching fm.exe from cmd itself not from my application.

     

    -Launching: fm.exe < mypipein, where mypipein has zero-size buffer and write-through flag, and everything works ok! Data is flushed and the result is shown in the console on the fly.

     

    -Launching: fm.exe > mypipeout, where mypipeout has default-size buffer and write-through flag, data is also flushed on the fly as soon as i input it in the console.

     

    -Launching: fm.exe < mypipein > mypipeout, same configurations as above... failure, reader hangs.

     

    This is quite redundant because Process use pipes for redirection but i'm starting to fear that the problem goes beyond pipes, but the way Windows manages the whole stuff, this would explain the behavior that Rudy suggested... and perhaps there's no workaround.

    • Marked as answer by Paul Zhou Monday, August 29, 2011 6:07 AM
    Sunday, August 28, 2011 10:49 PM
  • That reminds me of an Old New Thing blog post. http://blogs.msdn.com/b/oldnewthing/archive/2011/07/07/10183884.aspx
    Sunday, August 28, 2011 10:53 PM
  • I've never found a work around.  But, I'm still teasing my brain over it.  Don't hold your breath.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Monday, August 29, 2011 12:01 AM