C#/IIS : Command line ouput can't be read when running under IIS

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • tvaughan77
    New Member
    • Jan 2008
    • 6

    C#/IIS : Command line ouput can't be read when running under IIS

    Hi,

    I have some code that I want to use to run a command line utility and I want to be able to run it from an aspx page running under IIS. The command line utility is a local utility running on the same box as my IIS server, and the code works in Visual Studio, just not under IIS. Any suggestions?

    The logs are totally silent on the issue. On line 36 (below), the log says:
    "I read this from our process:" . . . .just blank after that.

    Grrrr.....


    Code:
        public class CommandLineUtils : ICommandLineUtils
        {
            private static readonly ILog log = LogManager.GetLogger(typeof(CommandLineUtils));
    
            private StringBuilder processStdOutput = null;
    
            /// 
            /// <summary>
            /// Executes an Interwoven command line utility
            /// </summary>
            /// <param name="clt">The utility to execute</param>
            /// <param name="args">Any arguments to pass on the command line</param>
            /// <returns>The string of output, as produced by running the command</returns>
            /// 
            public string ExecIwovCLT(string clt, string args)
            {
                log.Debug("Executing command: '" + clt + " " + args + "'");
                processStdOutput = new StringBuilder("");
                
    
                Process proc = new Process();
                proc.StartInfo.FileName = clt;
                proc.StartInfo.Arguments = args;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardError = true;
    
                proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
                proc.ErrorDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
    
                try
                {
                    proc.Start();
                    proc.BeginOutputReadLine();
                    proc.WaitForExit();
                    log.Debug("I read this from our process: \n" + processStdOutput.ToString());
                }
                catch (Win32Exception ex)
                {
                    log.Error("Could not execute the '" + clt + " " + args + "' command");
                    log.Error(ex.ToString());
                }
                finally
                {
                    proc.Close();
                }
    
                return processStdOutput.ToString();
            }
    
    
            /// 
            /// <summary>
            /// Event handler for process execution method (above)
            /// </summary>
            /// <param name="sendingProcess">process doing the outputting</param>
            /// <param name="outLine">output line from the process</param>
            /// 
            private void proc_OutputDataReceived(object sendingProcess,
                                                 DataReceivedEventArgs outLine)
            {
                if (!String.IsNullOrEmpty(outLine.Data))
                {                
                    processStdOutput.Append(outLine.Data + Environment.NewLine);
                }
            }
        }
    }
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    I don't see anywhere where you actually read the data from the process (the in/out/error streams)
    I see you have the eventhandlers, but they don't seem to ever look at the streams?

    Comment

    • tvaughan77
      New Member
      • Jan 2008
      • 6

      #3
      Originally posted by Plater
      I don't see anywhere where you actually read the data from the process (the in/out/error streams)
      I see you have the eventhandlers, but they don't seem to ever look at the streams?
      The line:
      Code:
      processStdOutput.Append(outLine.Data + Environment.NewLine);
      is appending Stdout and Stderr lines to a StringBuffer class member variable.

      I know that part works (i.e. that I can actually read stuff from a command line handle) because when I run this in my IDE and I try executing the DOS command "date" (for example), I can read the process' output and I echo the correct time.

      When I move this code in to IIS, however, I just read nothing. . .an empty line.

      BTW, I found out that the exit code of the Process is "1", but that's all the info I can get...it isn't throwing an exception or telling me why it's erroring out.

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        Yeah, sorry, I went crosseyed and realized I was reading the eventhandlers wrong (oops).

        Even if it exited with a zero, shouldn't it dump data into the error stream?

        Maybe it never actually executed the file you are trying to run. Like if you tried to run a .vbs file but didn't have vbscript support on the computer. It wouldn't return any data to the in/out/error streams because it couldn't do anything, that would return a non-zero value for the return code.
        Have you tried manually running the process on the IIS server machine?

        Comment

        • tvaughan77
          New Member
          • Jan 2008
          • 6

          #5
          Originally posted by Plater
          Yeah, sorry, I went crosseyed and realized I was reading the eventhandlers wrong (oops).

          Even if it exited with a zero, shouldn't it dump data into the error stream?

          Maybe it never actually executed the file you are trying to run. Like if you tried to run a .vbs file but didn't have vbscript support on the computer. It wouldn't return any data to the in/out/error streams because it couldn't do anything, that would return a non-zero value for the return code.
          Have you tried manually running the process on the IIS server machine?
          Yep, in my logs, I echo exactly what I'm trying to run:
          Code:
          Executing command: 'C:\Interwoven\TeamSite\bin\iwgetwfobj.exe 123'
          I read this from our process: 
          
          2008-01-04 11:08:18,583 DEBUG The process exit code is: '1'
          So if I copy and paste the command onto a DOS prompt on that server, I get the expected output (about 20 lines of XML).

          Weird, huh?

          To make things more weird, I even tried running some other command just before the iwgetwjobj command....and that works!

          Just before I try running the iwgetwjobj.exe, I run "c:\\cygwin\\bi n\\ps.exe" and it returns a list of processes currently running on that server, and that works when I run it on the command line, from within my IDE, and (crucially) while running under IIS.

          So I'm really kind of stuck as to why one exe will work and the other won't.
          Both exe's have the same permissions (Everyone has Full Control).

          Comment

          • Plater
            Recognized Expert Expert
            • Apr 2007
            • 7872

            #6
            Did you run the ps.exe process in the same manor? capturing it's output(s) and setting shellexecute to false?

            Comment

            • tvaughan77
              New Member
              • Jan 2008
              • 6

              #7
              Originally posted by Plater
              Did you run the ps.exe process in the same manor? capturing it's output(s) and setting shellexecute to false?
              Yep; exactly the same method used in both cases.
              Code:
                      public string GetReviewTaskOwner(int taskid)
                      {
                          //
                          // FIXME remove this ps.exe debugging call:
                          //
                          string testcommand = "C:\\cygwin\\bin\\ps.exe";
                          string testoutput = clUtils.[B]ExecIwovCLT[/B](testcommand, "");
                          log.Debug("The testoutput of running " + testcommand + " is \n'" + testoutput + "'\n");
              
                          //
                          //  This is where the iwgetwfobj call is made
                          //
                          string fullPathClt = Path.Combine(iwbin, iwgetwfobj);            
                          string args = "" + taskid;
                          string commandLineOutput = clUtils.[B]ExecIwovCLT[/B](fullPathClt, args);
                          
                          string owner = getOwnerFromWfObjXML(commandLineOutput);
                          
                          return owner;
                      }

              Comment

              Working...