none
Process StandardInput and CMD call issues RRS feed

  • Question

  •  

    Hello,

    I am having a problem wiriting a string to the redirected standardinput for my process.start.

    I have a string that is roughly 400,000 chars long, and i need to write it to the process.standardinput so i can then call my pgp encrpytion and encrypt the string.

     

    All works well until  my string gets to a cetain length (139,000 chars), then on the

    StandardInput.WriteLine, it hangs and seats until i kill the process.

     

    code

    _______________________

    static string send = "--homedir \"C:\\gnupg\" --yes --batch --encrypt --armor --recipient bhull@racetrac.com --verbose " ;

    static ProcessStartInfo startinfo = new ProcessStartInfo(@"C:\gnupg\gpg.exe" , send);

    string _ResultSet; // This is a file a block of data from a database.

    static Process procstart;

    static string _outputString;

    startinfo.CreateNoWindow = true;

    startinfo.UseShellExecute = false;

    startinfo.RedirectStandardInput = true;

    startinfo.RedirectStandardOutput = true;

    startinfo.RedirectStandardError = true;

    startinfo.RedirectStandardOutput = true;

    startinfo.CreateNoWindow = true;

    startinfo.WorkingDirectory = GnupgHome;

    procstart = Process.Start(startinfo);

    procstart.StandardInput.AutoFlush = false;

    procstart.StandardInput.WriteLine(_ResultSet); ///Locks here if length is over 139,000

    procstart.StandardInput.Close();

     

    ThreadStart outputEntry = new ThreadStart(StandardOutputReader);

    Thread outputThread = new Thread(outputEntry);

    outputThread.Start();

     

    if (procstart.WaitForExit(10000))

    {

    if (!outputThread.Join(10000 / 2))

    {

    outputThread.Abort();

    }

    }

    else

    {

    procstart.Kill();

    if (outputThread.IsAlive)

    {

    outputThread.Abort();

    }

    }

    string outputText = "";

    if (procstart.ExitCode == 0)

    {

    outputText = _outputString;

    }

     

    static void StandardOutputReader()

    {

    string output = procstart.StandardOutput.ReadToEnd();

    _outputString = output;

    }

     

    I cannot seperate the string and run multiple processes to encrpyt it because i need it all i none file. 

    I cannot write the _ResultSet out to a file because the data is sensitive and we want no clear text ever.

     

    Can anyone help?

    Thursday, May 22, 2008 7:24 PM

Answers

  • Well, the theory is that it actually starts outputting results well before you are ready to read them.  That output goes into a buffer, everything stops when the buffer is filled to capacity.  You start reading too late.

    Here's the link, my post editor was mangling it:

    http://www.google.com/search?hl=en&q=c%23+pgp&revid=115541330&sa=X&oi=revisions_inline&resnum=0&ct=revision&cd=1
    Thursday, May 22, 2008 9:09 PM
    Moderator
  • I guess you create a deadlock on your own thread. You need to create an extra thread for the writing of data also because the started process will generate some output data as well which will fill its internal buffer but you are still sending messages but you do not read yet;

     

     

    procstart = Process.Start(startinfo);

    procstart.StandardInput.AutoFlush = false;

    procstart.StandardInput.WriteLine(_ResultSet); ///Locks here if length is over 139,000

    procstart.StandardInput.Close();

     

    becomes

    procstart = Process.Start(startinfo);

    procstart.StandardInput.AutoFlush = false;

     

    Thread writer = new Thread( delegate()

    {

    procstart.StandardInput.WriteLine(_ResultSet); ///Locks here if length is over 139,000

    procstart.StandardInput.Close();

    };

     

    writer.Start();

     

    ....

     

    writer.Join();

     

     

    That should do the trick.

     

    Yours,

       Alois Kraus

     

     

    Tuesday, May 27, 2008 11:44 AM

All replies

  • At what point does this program start spitting out results?  If it does so while still reading data from the input stream, some output buffer is going to get filled to capacity and stall the program.  Try starting your output reader thread earlier.  Check this Google query for a way to avoid having to use another process.
    Thursday, May 22, 2008 8:19 PM
    Moderator
  •  

    The link seems to not go anywhere.

     

    The app will not spit out results until it calls the

    StandardOutputReader() on the outputThread.start()

     

    At this time, the StandardInput will have finished.  But ithe process does not get to this point .  In the code above, it hangs and stops at the line i marked   (procstart.StandardInput.WriteLine(_ResultSet)) 

    It never gets to the code to read StandardOutput if the string variable is too large.

     

    Thanks for hte help

    Thursday, May 22, 2008 8:49 PM
  • Well, the theory is that it actually starts outputting results well before you are ready to read them.  That output goes into a buffer, everything stops when the buffer is filled to capacity.  You start reading too late.

    Here's the link, my post editor was mangling it:

    http://www.google.com/search?hl=en&q=c%23+pgp&revid=115541330&sa=X&oi=revisions_inline&resnum=0&ct=revision&cd=1
    Thursday, May 22, 2008 9:09 PM
    Moderator
  •  

    Thanks for the post.  EasyByte PGP might be able to help.

    I wil verify later, after testing.

    Thursday, May 22, 2008 10:13 PM
  •  

    There are some 3rd party dlls that will work for a price.

    But this still does not solve my problem.  Why does the app lock when the buffer gets full?  How can I increase the buffer size? and if I can not increase the buffer size, how can i read the output data when it buffers, without spliting up the inputdata?

     

    Thanks

    Tuesday, May 27, 2008 11:01 AM
  • I guess you create a deadlock on your own thread. You need to create an extra thread for the writing of data also because the started process will generate some output data as well which will fill its internal buffer but you are still sending messages but you do not read yet;

     

     

    procstart = Process.Start(startinfo);

    procstart.StandardInput.AutoFlush = false;

    procstart.StandardInput.WriteLine(_ResultSet); ///Locks here if length is over 139,000

    procstart.StandardInput.Close();

     

    becomes

    procstart = Process.Start(startinfo);

    procstart.StandardInput.AutoFlush = false;

     

    Thread writer = new Thread( delegate()

    {

    procstart.StandardInput.WriteLine(_ResultSet); ///Locks here if length is over 139,000

    procstart.StandardInput.Close();

    };

     

    writer.Start();

     

    ....

     

    writer.Join();

     

     

    That should do the trick.

     

    Yours,

       Alois Kraus

     

     

    Tuesday, May 27, 2008 11:44 AM
  • I do believe this will work.

    Thanks a lot.

     

    Tuesday, May 27, 2008 2:40 PM