C# c语言中的重定向标准输出问题#
您能解释一下为什么shell重定向不能与System.Diagnostics.Process类一起使用吗?我试图用以下代码段将输出流重定向到文件:C# c语言中的重定向标准输出问题#,c#,.net,C#,.net,您能解释一下为什么shell重定向不能与System.Diagnostics.Process类一起使用吗?我试图用以下代码段将输出流重定向到文件: Process p = new Process(); p.StartInfo = new ProcessStartInfo(); p.StartInfo.FileName = "java.exe"; p.StartInfo.Arguments = @"> c:\Temp\test.log 2>&1"; p.StartInfo.Us
Process p = new Process();
p.StartInfo = new ProcessStartInfo();
p.StartInfo.FileName = "java.exe";
p.StartInfo.Arguments = @"> c:\Temp\test.log 2>&1";
p.StartInfo.UseShellExecute = true;
p.Start();
类似的代码在使用Python时不会出现问题。
在我的例子中,以编程方式读取输出流似乎不是更好的解决方案,因为我的应用程序将启动一系列进程。这是因为没有shell来处理这些参数。 当您将命令行键入shell时,它将被解析,程序参数与shell“特殊”修饰符分开,然后才启动。 在C#中,这不会发生,因为没有“cmd.exe”或“bash”进程来执行 要在C#中重定向输入,应将
p.StartInfo.RedirectStandardOutput
设置为true,然后使用p.StandardOutput
读取数据,然后将其写入文件
或者,您可以使用执行进程和重定向其输出所需的参数运行“cmd.exe”。虽然不是跨平台的,但这应该比自己编写高效的数据流传递实现更容易。这是因为没有shell来处理这些参数。 当您将命令行键入shell时,它将被解析,程序参数与shell“特殊”修饰符分开,然后才启动。 在C#中,这不会发生,因为没有“cmd.exe”或“bash”进程来执行 要在C#中重定向输入,应将
p.StartInfo.RedirectStandardOutput
设置为true,然后使用p.StandardOutput
读取数据,然后将其写入文件
或者,您可以使用执行进程和重定向其输出所需的参数运行“cmd.exe”。虽然不是跨平台的,但这应该比自己编写高效的数据流传递实现更容易。如果要重定向输出流,必须对其进行配置。设置
重定向…
属性并读取流。你可以找到一个例子
如果要重定向输出流,则必须对其进行配置。设置
重定向…
属性并读取流。你可以找到一个例子
关于您无法执行重定向,因为没有直接涉及的shell。您可以运行cmd.exe会话,但正确的方法是使用RedirectStandardOutput/Error属性。有许多进程时没有问题。这是我用来做这个的一个类
class HandleExecutable {
private DataReceivedEventHandler outputHandler;
public DataReceivedEventHandler OutputHandler
{
set { outputHandler = value; }
}
private DataReceivedEventHandler errorHandler;
public DataReceivedEventHandler ErrorHandler
{
set { errorHandler = value; }
}
public void callExecutable(string executable, string args)
{
string commandLine = executable;
string args = args;
ProcessStartInfo psi = new ProcessStartInfo(commandLine);
psi.UseShellExecute = false;
psi.LoadUserProfile = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WindowStyle = ProcessWindowStyle.Minimized;
psi.CreateNoWindow = true;
psi.Arguments = args;
p = new Process();
p.StartInfo = psi;
try
{
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
if (outputHandler != null) p.OutputDataReceived += outputHandler;
if (errorHandler != null) p.ErrorDataReceived += errorHandler;
p.WaitForExit();
p.Close();
p.Dispose();
}
catch (Exception ex)
{
log.Error(ex.Message);
}
}
}
//On another class
void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
//HANDLE STDERR
if (e.Data != null && !e.Data.Equals(""))
{
if (!e.Data.Contains("Something")) {
}
}
}
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
//HANDLE STDOUT
if (e.Data != null && !e.Data.Equals(""))
{
}
}
HandleExecutable he = new HandleExecutable();
he.OutputHandler = p_OutputDataReceived;
he.ErrorHandler = p_ErrorDataReceived;
he.callExecutable(@"C:\java.exe","-cp foo ClassName");
无法执行重定向,因为没有直接涉及的shell。您可以运行cmd.exe会话,但正确的方法是使用RedirectStandardOutput/Error属性。有许多进程时没有问题。这是我用来做这个的一个类
class HandleExecutable {
private DataReceivedEventHandler outputHandler;
public DataReceivedEventHandler OutputHandler
{
set { outputHandler = value; }
}
private DataReceivedEventHandler errorHandler;
public DataReceivedEventHandler ErrorHandler
{
set { errorHandler = value; }
}
public void callExecutable(string executable, string args)
{
string commandLine = executable;
string args = args;
ProcessStartInfo psi = new ProcessStartInfo(commandLine);
psi.UseShellExecute = false;
psi.LoadUserProfile = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WindowStyle = ProcessWindowStyle.Minimized;
psi.CreateNoWindow = true;
psi.Arguments = args;
p = new Process();
p.StartInfo = psi;
try
{
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
if (outputHandler != null) p.OutputDataReceived += outputHandler;
if (errorHandler != null) p.ErrorDataReceived += errorHandler;
p.WaitForExit();
p.Close();
p.Dispose();
}
catch (Exception ex)
{
log.Error(ex.Message);
}
}
}
//On another class
void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
//HANDLE STDERR
if (e.Data != null && !e.Data.Equals(""))
{
if (!e.Data.Contains("Something")) {
}
}
}
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
//HANDLE STDOUT
if (e.Data != null && !e.Data.Equals(""))
{
}
}
HandleExecutable he = new HandleExecutable();
he.OutputHandler = p_OutputDataReceived;
he.ErrorHandler = p_ErrorDataReceived;
he.callExecutable(@"C:\java.exe","-cp foo ClassName");
但是我将ProcessStartInfo.UseShellExecute设置为true,以便使用shell启动进程。在这种情况下,ProcessStartInfo.UseShellExecute的含义是什么?谢谢@这大致相当于双击一个注册文件,或者在命令行中使用
start foo.doc
,它对给定的文件类型使用shell的处理程序。“UseShellExecute=false”在WindowsService环境中以域用户身份登录时,大致不允许进程与文件系统交互,但我将ProcessStartInfo.UseShellExecute设置为true,以便使用壳在这种情况下,ProcessStartInfo.UseShellExecute的含义是什么?谢谢@这大致相当于双击一个注册文件,或者在命令行中使用start foo.doc
——它对给定的文件类型使用shell的处理程序。“UseShellExecute=false”在WindowsService环境中以域用户身份登录时,大致不允许进程与文件系统交互。理想情况下,您应该在开始读取之前设置事件处理程序。如果不这样做,您将有丢失第一位输出的风险。例如,理想情况下,您应该在开始读取之前设置事件处理程序。如果不这样做,您将有丢失第一位输出的风险。有关示例,请参见