Process Standard Output Problem

MTSkull

Centurion
Joined
Mar 25, 2003
Messages
151
Location
Boulder, Colorado
I am launching a process that uploads a file to a remote server. Then I will launch a second process that will run a script on the remote server to process the file. All of which works except...

I would like to read the console outputs so i can tell if what I am doing is working. When I set up the process to redirect to a standard output stream, if I call any of the Read(), ReadBlock(), etc, commands, the program hangs. If I try to run the reads in an event, the event code never fires. If i call the Peek command I can see the First char that would be expected if I was running the console manually.

Is there something I can do to get the read to work?

Thanks
MTS

EDIT: This is in code behind for a aspx page, Should this be posted else where?

Some code to peruse...
Code:
public void UploadFileViaPSFTP(string ServerName, string UserName, string Password, string FileName)
        {

            // open log file, overwrite existing
            StreamWriter ftpLog = new StreamWriter("C:\\psftpLog.txt", false); // create a new log file
            ftpLog.WriteLine("Start Copy Process:" + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString());
            ftpLog.Close();

            // loop variables
            int loopThrottle = 250; // controls how fast the loop sends commands to the process
            // : 1000   works
            // : 500    works
            // : 250    works, will use this for now
            // : 100    is too fast, transfer does not happen

            string[] commands = new string[]{"open " + ServerName,
                                             UserName,
                                             Password,
                                             "put \"" + FileName + "\""}; // file name and path needs double quotes

            // Setup psftp process
            // psftp.exe download from "http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"
            //    select putty.zip for multiple utilities
            Process psftp = new Process();

            psftp.StartInfo.UseShellExecute = false; // has to be false to allow stream redirection
            psftp.StartInfo.FileName = "C:\\ssh_tools\\psftp.exe"; // allows uploading a file to a remote server
            psftp.StartInfo.CreateNoWindow = true;

            // event handler for psftp data output
            // Does not work, will troubleshoot as needed
            //psftp.OutputDataReceived += new DataReceivedEventHandler(RedirectConsoleToTextFile);

            // allow console input/out stream redirection
            psftp.StartInfo.RedirectStandardInput = true;
            psftp.StartInfo.RedirectStandardOutput = true;

            // Start Process, 
            psftp.Start();

            System.Threading.Thread.Sleep(loopThrottle);
            StreamWriter psftpIn = psftp.StandardInput; // redirect input to console

            // Hangs, never returns data
            //string data = psftp.StandardOutput.ReadToEnd();

            //Will see the first char in the console output! Grrr, how do I read this?
            int data = psftp.StandardOutput.Peek();

            //Loop to send console commands
            for (int x = 0; x < commands.Length; x++)
            {
                psftpIn.WriteLine(commands[x]);
                System.Threading.Thread.Sleep(loopThrottle);
            }

            // give things a chance to settle
            System.Threading.Thread.Sleep(loopThrottle * 5);

            // clean up...
            psftpIn.Close();
            psftp.Close();

        }
        private static void RedirectConsoleToTextFile(object sendingProcess, DataReceivedEventArgs outLine)
        {
            bool append = true;
            
            // redirect console output to text file
            // NOTE: never fires
            if (String.IsNullOrEmpty(outLine.Data) != true)
            {
                if (File.Exists("C:\\psftpLog.txt") != true)
                    append = false; // create the file if it does not exist

                StreamWriter ftpLog = new StreamWriter("C:\\psftpLog.txt", append);

                ftpLog.Write(outLine.ToString());

                ftpLog.Close();
            }
        }
 
Figured it out. You cannot access the redirected output or error data while the process is running. once the process has stopped then you can look at the data. I think because I am actively sending data and have to explicitly send an "exit" command, the output is unavailable.

The following mods to previously posted code work.
Code:
public void UploadFileViaPSFTP(string ServerName, string UserName, string Password, string FileName)
        {
            // loop variables
            int loopThrottle = 1000; // controls how fast the loop sends commands to the process
            // : 1000   works
            // : 500    works
            // : 250    works, will use this for now
            // : 100    is too fast, transfer does not happen

            string[] commands = new string[]{"open " + ServerName,
                                             UserName,
                                             Password,
                                             "put \"" + FileName + "\"",// file name and path needs double quotes
                                             "ls",
                                             "exit"}; 

            // Setup psftp process
            // psftp.exe download from "http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"
            //    select putty.zip for multiple utilities
            Process psftp = new Process();

            psftp.StartInfo.UseShellExecute = false; // has to be false to allow stream redirection
            psftp.StartInfo.FileName = Server.MapPath("SSH_Tools") + "\\psftp.exe"; // allows uploading a file to a remote server
            psftp.StartInfo.CreateNoWindow = true;

            // allow console input/out stream redirection
            psftp.StartInfo.RedirectStandardInput = true;
            psftp.StartInfo.RedirectStandardOutput = true;
            psftp.StartInfo.RedirectStandardError = true;

            // Start Process, 
            psftp.Start();

            System.Threading.Thread.Sleep(loopThrottle);
            StreamWriter psftpIn = psftp.StandardInput; // redirect input to console

            //Loop to send console commands
            for (int x = 0; x < commands.Length; x++)
            {
                psftpIn.WriteLine(commands[x]);
                System.Threading.Thread.Sleep(loopThrottle);
            }

            // give things a chance to settle
            System.Threading.Thread.Sleep(loopThrottle * 5);

            psftp.WaitForExit();

            LogToTextFile("UploadFileViaPSFTP", commands, psftp.StandardOutput, psftp.StandardError);

            // clean up...
            psftpIn.Close();
            psftp.Close();

        }

private void LogToTextFile(string processName, string[] commands, StreamReader Output, StreamReader Error)
        {
            string filename = Server.MapPath("SSH_Tools") + "\\ErrorLog.txt";
            string dtStamp = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ": ";

            StreamWriter ftpLog = new StreamWriter(filename, true);

            ftpLog.WriteLine();
            ftpLog.WriteLine("<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>");
            ftpLog.WriteLine();

            ftpLog.WriteLine(dtStamp + processName);

            // write commands
            for (int x = 0; x < commands.Length; x++)
                ftpLog.WriteLine(string.Format("{0}COMMAND: [{1}]: {2}",dtStamp, x, commands[x]));

            // write output data
            if (Output.EndOfStream == true)
                ftpLog.WriteLine(dtStamp + "OUTPUT : EOF, no output available.");
            else
            {
                while (Output.EndOfStream != true)
                    ftpLog.WriteLine(dtStamp + "OUTPUT : " + Output.ReadLine());
            }

            //write error data
            if (Error.EndOfStream == true)
                ftpLog.WriteLine(dtStamp + "ERROR  : EOF, no error available");
            else
            {
                while (Error.EndOfStream != true)
                    ftpLog.WriteLine(dtStamp + "ERROR  : " + Error.ReadToEnd());
            }

            ftpLog.Close();
            
        }
 
Back
Top