【发布时间】:2019-08-25 18:39:50
【问题描述】:
我有一个应用程序(不归我所有),只要它们实现特定接口作为入口点,就可以执行编译为 DLL 的“插件”。
使用此配置,控制我的插件 DLL 代码执行的进程与该应用程序相同(因此涉及单个进程),但我不控制该进程的启动。这意味着我无法设置
StartInfo.UseShellExecute = false;
StartInfo.RedirectStandardOutput = true;
似乎需要访问标准输出(基于我找到的其他答案)......正在执行我的插件的进程似乎已经将那些设置为“错误”值(UseShellExecute = true和 RedirectStandardOutput = false)。
所以...我的插件可以使用此应用程序的 API 调用一个函数,该函数会导致应用程序执行长时间运行的计算。调用此函数会导致我的代码暂停执行,直到此函数完成其处理(即它是同步的)。
我希望在单独的线程上添加进度指示器,但来自父应用程序的唯一通信似乎被写入标准输出。我这样说的原因是,当我让 Visual Studio 调试应用程序时,即使我的代码在该函数的执行中“冻结”(see here)
,我也可以在“输出”选项卡中看到“Progress X%”更新所以我的问题是:有什么方法可以捕获这个输出?我试过了
process.ErrorDataReceived += Process_ErrorDataReceived;
process.OutputDataReceived += ProcessOnOutputDataReceived;
但那些似乎从未被调用(因为父应用程序似乎以 UseShellExecute = true 和 RedirectStandardOutput = false 启动,并且我不控制进程的启动)
我还尝试了自定义 ConsoleWriter(在单独的线程上)
consoleWriter = new MyConsoleWriter();
consoleWriter.WriteEvent += MyCustomWrite;
consoleWriter.WriteLineEvent += MyCustomWriteLine;
Console.SetOut(consoleWriter);
尽管我在 Visual Studio 中看到了明显的输出消息,但它从未被使用(我认为这意味着父应用程序没有使用 .NET 控制台?)
鉴于我无法控制 process.StartInfo.UseShellExecute 和 process.StartInfo.RedirectStandardOutput(好吧,我可以随时更改它们,但我认为除了进程启动时它没有任何影响),但是我确实与父应用程序共享相同的进程(即我的代码正在由同一进程执行),有人知道我如何可能捕获这些写入(似乎是)这个父应用程序的标准输出吗?
【问题讨论】:
-
不幸的是,对于这样一个不完整的问题,不可能知道在您的场景中究竟什么会起作用。如果您正在处理托管进程,则可以使用
Console.SetOut(),如果没有其他技术。在所有的情况下,你应该非常小心;重定向不属于您的进程的输出可能会导致与尝试执行相同操作的其他代码发生冲突,包括进程的实际所有者。 -
只有在您开始异步阅读时才会触发这些事件(
BeginOutputReadLine()和BeginErrorReadLine())。否则,您必须同步读取相应的流(通过StandardOutput和StandardError属性)。