简体   繁体   中英

How can I obtain console application output when running it as a process in a C# DLL file?

I am working on method in a DLL. In my method I have been writing to the event log to allow me to determine whether things are working as I expect. One of the tasks I do in the method is create a process and run a command line application and I want to be able to capture the output of this that is normally written to the console and write it to the eventlog.

Code:

Process getNextIons = new Process();
getNextIons.StartInfo.FileName = @"""C:\Program Files\OpenMS-1.6\PrecursorIonSelector.exe""";
getNextIons.StartInfo.Arguments = @"-ini ""C:\Program Files\OpenMS-1.6\precursorionselector.ini""";
getNextIons.StartInfo.UseShellExecute = false;
getNextIons.StartInfo.RedirectStandardOutput = true;
getNextIons.Start();
getNextIons.WaitForExit();
System.Diagnostics.EventLog.WriteEntry("FMANWiff", "IPS: " + getNextIons.StandardOutput.ReadToEnd());

I have a console test application that calls my method and when I do this I am able to see that the process was started and ran correctly, however when I actually try to make use of the DLL, not using the test application, all I end up seeing is an entry:

IPS: And none of the output. I can tell it is running, however, as I can see a number of output files being updated.

Why am I not getting any output and how I can rectify this?

According to the Process.StandardOutput documentation your code has a potential deadlock.

When the caller reads from the redirected stream of a child process, it is dependent on the child. The caller waits on the read operation until the child writes to the stream or closes the stream. When the child process writes enough data to fill its redirected stream, it is dependent on the parent. The child process waits on the next write operation until the parent reads from the full stream or closes the stream. The deadlock condition results when the caller and child process wait on each other to complete an operation, and neither can proceed.

To avoid the possible deadlock, the last two lines of your sample code should be switched. You should also consider redirecting StandardError.

In your library, instead of writing directly to the location of choice you should be using System.Diagnostics.Trace . By using Trace you can have your outside console application or whatever it be subscribe to the Trace event using a TraceListener .

By using Trace and TraceListeners, you can make you application adaptable to whatever logging situation you require without having to modify your library every time you want to change the logging system.

Below is a link to another Stack Overflow thread about trace logging with some good examples and information.

How can I add (simple) tracing in C#?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM