0

I have an application (not owned by me) that can execute "plugins" compiled as DLLs so long as they implement a specific interface as an entry point.

With this configuration, the Process controlling my plugin DLL's code execution is the same as that application (so a single Process is involved), but I don't control the startup of that Process. This means I cannot set

StartInfo.UseShellExecute = false;
StartInfo.RedirectStandardOutput = true;

as seems to be required for getting access to Standard Output (based on other answers I've found)... the Process that is executing my plugin seems to already have those set to the "wrong" values (UseShellExecute = true and RedirectStandardOutput = false).

So... my plugin can call a function using this application's API that causes the application to perform a long-running calculation. Calling this function results in execution of my code pausing until this function completes its processing (i.e. it's synchronous).

I would love to add a progress indicator on a separate thread, but the only communication from the parent application appears to be written to the Standard Output. The reason I say this is that when I have Visual Studio debugging the application, I can see "Progress X%" updates in the Output tab even while my code is "frozen" on that function's execution (see here)

So my question is: is there any way to capture this output? I have tried

process.ErrorDataReceived += Process_ErrorDataReceived;
process.OutputDataReceived += ProcessOnOutputDataReceived;

but those never seem to get called (since the parent application appears to be started with UseShellExecute = true and RedirectStandardOutput = false, and I don't control the starting of the Process)

I've also tried a custom ConsoleWriter (on a separate thread)

 consoleWriter = new MyConsoleWriter();
 consoleWriter.WriteEvent += MyCustomWrite;
 consoleWriter.WriteLineEvent += MyCustomWriteLine;
 Console.SetOut(consoleWriter);

But it is never utilized in spite of the apparent Output messages I see in Visual Studio (I presume that means that the parent application does not utilize the .NET Console?)

Given that I don't have control over process.StartInfo.UseShellExecute and process.StartInfo.RedirectStandardOutput (well, I can change them whenever but I don't think it has any effect except when the process is started), but that I do share the same Process as the parent application (i.e. my code is being executed by the same process), does anybody know how I could possibly capture these writes to (what seems to be) the Standard Output of this parent application?

  • Unfortunately, with such an incomplete question, it's impossible to know what exactly would work in your scenario. If you are dealing with a managed process, you may be able to use `Console.SetOut()`, if not there are other techniques. In _all_ cases, you should tread very carefully; redirecting the output of a process you don't own can lead to conflicts with other code trying to do the same, including the _actual owner_ of the process. – Peter Duniho Aug 25 '19 at 19:15
  • Those events will be triggered only if you started reading asynchronously (`BeginOutputReadLine()` and `BeginErrorReadLine()`). Otherwise you'll have to read from the corresponding streams synchronously (via the `StandardOutput` and `StandardError` properties). – Jeff Mercado Aug 25 '19 at 19:24

1 Answers1

0

It occurred to me that the visual studio Output tab must be printing more than just Console output, which led me here: https://learn.microsoft.com/en-us/visualstudio/debugger/diagnostic-messages-in-the-output-window?view=vs-2019

And indeed, when I added a TraceListener (I started with just a Console I was able to capture this output. I started with a simple ConsoleTraceListener and it worked.

Beware of the warnings about TraceListeners that are still hanging out (I could see this being an issue for my application) https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.trace?view=netframework-4.8