我也猜测并非所有的应用程序都正确使用stderr和stdout,因此您可能在“控制台应用程序”中看到的内容没有提供您期望的信息。
如果没有更多重定向stderr,也可以让你看看它是否与语法相关,并且应用程序抛出异常。
startInfo.RedirectStandardError = true;
我想补充到,在一个类中封装起来,你可以用cmd shell类型的互动,而不是仅仅运行和返回...如果你想默默自动化的应用程序,这是可能你想要的方法...
我刚刚写了一个这样的人在VB中的一个样本,语法可能很粗糙,因为我在多年未启动VB,但你得到它的要点,应该能够很容易在C#中复制。这是一个粗略的草稿如何类型的方法,而不是一段代码我会打电话的生产准备,授人以鱼样本;)
#Region " Imports "
Imports System.Threading
Imports System.ComponentModel
#End Region
Namespace Common
Public Class CmdShell
#Region " Variables "
Private WithEvents ShellProcess As Process
#End Region
#Region " Events "
''' <summary>
''' Event indicating an asyc read of the command process's StdOut pipe has occured.
''' </summary>
Public Event DataReceived As EventHandler(Of CmdShellDataReceivedEventArgs)
#End Region
#Region " Public Methods "
Public Sub New()
ThreadPool.QueueUserWorkItem(AddressOf ShellLoop, Nothing)
Do Until Not ShellProcess Is Nothing : Loop
End Sub
''' <param name="Value">String value to write to the StdIn pipe of the command process, (CRLF not required).</param>
Public Sub Write(ByVal value As String)
ShellProcess.StandardInput.WriteLine(value)
End Sub
#End Region
#Region " Private Methods "
Private Sub ShellLoop(ByVal state As Object)
Try
Dim SI As New ProcessStartInfo("cmd.exe")
With SI
.Arguments = "/k"
.RedirectStandardInput = True
.RedirectStandardOutput = True
.RedirectStandardError = True
.UseShellExecute = False
.CreateNoWindow = True
.WorkingDirectory = Environ("windir")
End With
Try
ShellProcess = Process.Start(SI)
With ShellProcess
.BeginOutputReadLine()
.BeginErrorReadLine()
.WaitForExit()
End With
Catch ex As Exception
With ex
Trace.WriteLine(.Message)
Trace.WriteLine(.Source)
Trace.WriteLine(.StackTrace)
End With
End Try
Catch ex As Exception
With ex
Trace.WriteLine(.Message)
Trace.WriteLine(.Source)
Trace.WriteLine(.StackTrace)
End With
End Try
End Sub
Private Sub ShellProcess_ErrorDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs) Handles ShellProcess.ErrorDataReceived
If Not e.Data Is Nothing Then RaiseEvent DataReceived(Me, New CmdShellDataReceivedEventArgs(e.Data))
End Sub
Private Sub ShellProcess_OutputDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs) Handles ShellProcess.OutputDataReceived
If Not e.Data Is Nothing Then RaiseEvent DataReceived(Me, New CmdShellDataReceivedEventArgs(e.Data & Environment.NewLine))
End Sub
#End Region
End Class
<EditorBrowsable(EditorBrowsableState.Never)> _
Public Class CmdShellDataReceivedEventArgs : Inherits EventArgs
Private _Value As String
Public Sub New(ByVal value As String)
_Value = value
End Sub
Public ReadOnly Property Value() As String
Get
Return _Value
End Get
End Property
End Class
End Namespace
只是为了确保没有任何陷阱,我径自而在C#这样做肮脏
public class cmdShell
{
private Process shellProcess;
public delegate void onDataHandler(cmdShell sender, string e);
public event onDataHandler onData;
public cmdShell()
{
try
{
shellProcess = new Process();
ProcessStartInfo si = new ProcessStartInfo("cmd.exe");
si.Arguments = "/k";
si.RedirectStandardInput = true;
si.RedirectStandardOutput = true;
si.RedirectStandardError = true;
si.UseShellExecute = false;
si.CreateNoWindow = true;
si.WorkingDirectory = Environment.GetEnvironmentVariable("windir");
shellProcess.StartInfo = si;
shellProcess.OutputDataReceived += shellProcess_OutputDataReceived;
shellProcess.ErrorDataReceived += shellProcess_ErrorDataReceived;
shellProcess.Start();
shellProcess.BeginErrorReadLine();
shellProcess.BeginOutputReadLine();
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
}
void shellProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
doOnData(e.Data);
}
void shellProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
doOnData(e.Data);
}
private void doOnData(string data)
{
if (onData != null) onData(this, data);
}
public void write(string data)
{
try
{
shellProcess.StandardInput.WriteLine(data);
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
}
}
所以现在使用类似这样的
cmdShell test = new cmdShell();
test.onData += test_onData;
test.write("ping 127.0.0.1");
与此有关的地方
void test_onData(cmdShell sender, string e)
{
Trace.WriteLine(e);
}
您有一个完全交互式的cmd进程来写入和接收异步数据。
输出到窗口
C:\Windows>ping 127.0.0.1
Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Ping statistics for 127.0.0.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
咖啡,睡眠...笑
如果你真的想要的约会...
cmdShell test = new cmdShell();
test.onData += test_onData;
test.write("date");
息率输出
C:\Windows>date
The current date is: Wed 10/08/2014
或
cmdShell test = new cmdShell();
test.onData += test_onData;
test.write("echo %date%");
息率输出
C:\Windows>echo %date%
Wed 10/08/2014
顺便说一句,如果你还没有实际使用的代码呢,这个方法给出数据的异步,意义作为程序输出它被交付给你,所以如果你运行一个需要花费时间的进程,比如100个ping,traceroute等......你看到它们发生时,不必等待它完成并返回。
此外,您可以在期间将命令传递回应用程序,与取消,响应并更改语法或仅根据第一次运行的结果运行其他类似的东西。基本上你可以像对待你在cmd窗口中输入一样对待它,然后在那里接收反馈,将整个思考包装在一个正确的线程形式中(小心从其他线程更新Windows控件时),并且你将拥有一个模拟cmd提示符。
'这就是为什么我有麻烦'什么麻烦? “它不起作用”不是对问题的描述。它有什么作用?崩溃?给出错误?沦为奇点?什么都不做?你期望它做什么? – 2014-10-08 15:09:14
你的问题可能是'date'本身就会提示你输入一个新的日期(从命令行尝试它)。试着用'date/T'来输出日期,而不要求你给它任何输入。或者,您可能只需在标准输入中输入“enter”即可。 – 2014-10-08 15:12:00