由于StandardOutput不是反应性的,我需要一种方法来观察它。我知道Process类公开了一个事件,用于在编写输出时接收通知所以我使用这个扩展方法来获得标准输出的IObservable
public static class ProcessExtensions
{
public static IObservable<string> StandardOutputObservable(this Process process)
{
process.EnableRaisingEvents = true;
process.StartInfo.RedirectStandardOutput = true;
var received = Observable.FromEventPattern<DataReceivedEventHandler,DataReceivedEventArgs>(
handler => handler.Invoke,
h => process.OutputDataReceived += h,
h => process.OutputDataReceived -= h)
.TakeUntil(Observable.FromEventPattern(
h => process.Exited += h,
h => process.Exited -= h))
.Select(e => e.EventArgs.Data);
process.BeginOutputReadLine();
return received;
/* Or if cancellation is important to you...
return Observable.Create<string>(observer =>
{
var cancel = Disposable.Create(process.CancelOutputRead);
return new CompositeDisposable(
cancel,
received.Subscribe(observer));
});
*/
}
}
正如在这里找到的。但当我开始过程时
public sealed class ProgramHelper
{
private readonly Process _program = new Process();
public IObservable<string> ObservableOutput { get; private set; }
public ProgramHelper(string programPath, string programArgs)
{
_program.StartInfo.FileName = programPath;
_program.StartInfo.Arguments = programArgs;
}
public void StartProgram()
{
ConfigService.SaveConfig(
new Config(
new Uri(@"http://some.url.com")));
_program.Start();
ObservableOutput = _program.StandardOutputObservable();
}
}
...
[TestFixture]
public class When_program_starts
{
private ProgramHelper _program;
[Test]
public void It_should_not_complain()
{
//W
Action act = () => _program.StartProgram();
//T
act.ShouldNotThrow<Exception>();
}
}
我得到这个错误:
"StandardOut尚未重定向或进程尚未启动。"
谢谢你抽出时间。
编辑:将ProgramHelper编辑为
public ProgramHelper(string programPath, string programArgs)
{
_program.StartInfo.FileName = programPath;
_program.StartInfo.Arguments = programArgs;
_program.EnableRaisingEvents = true;
_program.StartInfo.UseShellExecute = false;
_program.StartInfo.RedirectStandardOutput = true;
}
但现在它抛出"访问被拒绝异常"。
我似乎没有权限以编程方式启动流程;如果我从控制台启动exe,它运行得很好。
进程启动后,您正在更改Process.StartInfo属性。
来自Process.StartInfo MSDN文档:
您可以更改StartInfo属性中指定的参数,直到您在进程上调用Start方法为止。启动进程后,更改StartInfo值不会影响或重新启动关联的进程。