我在设置一个创建并与python进程1交互的c#应用程序时遇到了问题。下面给出一个简单的例子。
编辑:对SO的进一步研究揭示我的问题可能是重复的。 .NET Framework中可能存在的相关已知错误包括here和here。似乎早在2014年,唯一简单的解决方法确实是要求子进程在stdOut和stdErr中编写内容。但我想知道这个假设是否正确,并想知道自2014年以来是否还没有修复?
我必须满足以下边界条件:
我的目的是:
之后,我想先检查StdOut和StdErr。我知道 python将以下信息写入 StdErr
Python 2.7.11(v2.7.11:6d1b6a68f775,2015年12月5日,20:32:19)[MSC v1500 32位(英特尔)]在win32上
我可以通过使用errorReader.Peek()并从errorReader 2读取基于字符的内容来获取此行。
然而,另一个过程的情况可能完全不同。即使使用Python,我也会遇到以下问题:当我想从outputReader初始读取时,它中没有任何内容,并且outputReader.Peek()似乎遇到了死锁。如上所述,对于outputReader.EndOfStream或outputReader.ReadToEnd()也是如此。那么我怎么知道stdOut 可以是否可以使用而不会造成死锁?
代码:
// create the python process StartupInfo object
ProcessStartInfo _tempProcessStartInfo = new ProcessStartInfo(@"C:\TMP\Python27\python.exe");
// ProcessStartInfo _tempProcessStartInfo = new ProcessStartInfo(PathToPython + "python.exe");
// python uses "-i" to run in interactive mode
_tempProcessStartInfo.Arguments = "-i";
// Only start the python process, but don't show a (console) window
_tempProcessStartInfo.WindowStyle = ProcessWindowStyle.Minimized;
_tempProcessStartInfo.CreateNoWindow = true;
// Enable the redirection of python process std's
_tempProcessStartInfo.UseShellExecute = false;
_tempProcessStartInfo.RedirectStandardOutput = true;
_tempProcessStartInfo.RedirectStandardInput = true;
_tempProcessStartInfo.RedirectStandardError = true;
// Create the python process object and apply the startupInfos from above
Process _tempProcess = new Process();
_tempProcess.StartInfo = _tempProcessStartInfo;
// Start the process
bool _hasStarted = _tempProcess.Start();
//// ASynch reading seems not appropriate to me:
// _tempProcess.BeginOutputReadLine();
// _tempProcess.BeginErrorReadLine();
// Create StreamReaders and Writers for the Std's
StreamReader outputReader = _tempProcess.StandardOutput;
StreamReader errorReader = _tempProcess.StandardError;
StreamWriter commandWriter = _tempProcess.StandardInput;
// Create StringBuilder that collects results and ErrorMessages
StringBuilder tmp = new StringBuilder("");
// Create temp variable that is used to peek into streams. C# uses -1 to indicate that there is no more byte to read
int currentPeek = -1;
// Get Initial Error Message. In this specific case, this is the python version
tmp.AppendLine("INITIAL ERROR MESSAGE:");
currentPeek = errorReader.Peek();
while (currentPeek >= 0)
{
char text = (char)errorReader.Read();
tmp.Append(text);
currentPeek = errorReader.Peek();
}
// Get initial output Message. In this specific case, this is EMPTY, which seems to cause this problem, as ...
tmp.AppendLine("INITIAL STDOUT MESSAGE:");
//// ... the following command CREATES a well defined output, and afterwards everything works fine (?) but ...
//commandWriter.WriteLine(@"print 'Hello World'");
//// ... without the the above command, neither
//bool isEndOfStream = outputReader.EndOfStream;
//// ... nor
// currentPeek = outputReader.Peek();
//// ... nor
// tmp.AppendLine(outputReader.ReadLine());
//// ... nor
//tmp.AppendLine(outputReader.ReadToEnd());
//// ... works
// Therefore, the following command creates a deadlock
currentPeek = outputReader.Peek();
while (currentPeek >= 0)
{
char text = (char)outputReader.Read();
tmp.Append(text);
currentPeek = errorReader.Peek();
}
_currentPythonProcess = _tempProcess;
return true;
1对这个非常具体的问题的一个简单的解决方法是首先向进程发送一个有效的命令,例如简单地" 4",它返回一个" 4"以及...但是,我想了解流程,管道和相应的读者和作者如何工作以及如何在C#中使用它们。谁知道未来会带来什么,也许当pythons响应长度为2 ^ n + 1个字节时,我遇到缓冲问题... 2我知道我也可以阅读基于行的。但是,Peek()阻止我报告与截断行相关的问题。
答案 0 :(得分:0)
如果您可以等待进程结束然后再读取缓冲区,则可以使用Process.WaitForExit。您还可以检查另一种方法Process.WaitForInputIdle,但这取决于具有消息循环的进程,我不认为<?php
$fileName = preg_replace("#\?.*$#", "", basename("http://localhost/mc/site-01-up/index.php?c=lorem-ipsum"));
echo $fileName; // DISPLAYS: index.php
// OR SHORTER AND SIMPLER:
$fileName = basename($_SERVER['PHP_SELF']);
echo $fileName; // DISPLAYS: index.php
脚本在执行时会得到。