views:

129

answers:

2

I am attempting to wrap a 3rd party command line application within a web service.

If I run the following code from within a console application:

Process process= new System.Diagnostics.Process();
process.StartInfo.FileName = "some_executable.exe";

// Do not spawn a window for this process
process.StartInfo.CreateNoWindow = true;
process.StartInfo.ErrorDialog = false;

// Redirect input, output, and error streams
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.EnableRaisingEvents = true;


process.ErrorDataReceived += (sendingProcess, eventArgs) => {
    // Make note of the error message
    if (!String.IsNullOrEmpty(eventArgs.Data))
        if (this.WarningMessageEvent != null)
            this.WarningMessageEvent(this, new MessageEventArgs(eventArgs.Data));
};

process.OutputDataReceived += (sendingProcess, eventArgs) => {
    // Make note of the message
    if (!String.IsNullOrEmpty(eventArgs.Data))
        if (this.DebugMessageEvent != null)
            this.DebugMessageEvent(this, new MessageEventArgs(eventArgs.Data));
};

process.Exited += (object sender, EventArgs e) => {
    // Make note of the exit event
    if (this.DebugMessageEvent != null)
        this.DebugMessageEvent(this, new MessageEventArgs("The command exited"));
};

process.Start();
process.StandardInput.Close();
process.BeginOutputReadLine();
process.BeginErrorReadLine();

process.WaitForExit();

int exitCode = process.ExitCode;
process.Close();
process.Dispose();

if (this.DebugMessageEvent != null)
    this.DebugMessageEvent(this, new MessageEventArgs("The command exited with code: " + exitCode));

All events, including the "process.Exited" event fires as expected. However, when this code is invoked from within a web service method, all events EXCEPT the "process.Exited" event fire.

The execution appears to hang at the line:

process.WaitForExit();

Would anyone be able to shed some light as to what I might be missing?

A: 
tommieb75
The command is a tool written by a 3rd party and is not a common Windows command.We are using close to a dozen command line tools from this provider and the above code works fine for some executables of that vendor, oddly enough, but not all. As I mentioned earlier, using the above code to invoke the ActivePerl interpreter (http://www.activestate.com/activeperl) works perfectly.
Pizon
I understand your line of questioning regarding the input stream. You may have noticed I am immediately closing the standard input stream. There is nothing in the documentation provided by our 3rd party vendor regarding interactive input (everything should be handled as command arguments). Moreover, the same code run as a console application on my development workstation behaves as expected.
Pizon
For the time being, the web service is run with my own Active Directory credentials (as set in the application pool) on a development web server (IIS7 on 64-bit Windows 2008 server R2 standard).
Pizon
+1  A: 

As it turns out the problem was caused by the executable that I was trying to invoke.

Unfortunately, this 3rd party executable was a port of a UNIX command that was being run through a kind of emulator. The executable was designed to output messages to the output and error streams as one would expect. However, the toolkit our vendor used to port the binaries over to Windows does not use the standard output streams.

When I stepped through the web service and manually invoked the process from the command line, I saw the emulator display an error dialog box. From the C# point of view, the process does not complete unless the [OK] button is clicked on the dialog box hence the "Exited" event never fires.

After speaking with our vendor for the executable I learned it is not fully supported in 64-bit Windows. I installed the web service on a 32-bit environment and everything was fine.

Pizon