来自cmd的结果
C:\Users\XXXXX>adb start-server
* daemon not running. starting it now *
* daemon started successfully *
C:\Users\XXXXX>
我的c#代码。
public string devicesPlus()
{
psi.Arguments = "start-server";
call = Process.Start(psi);
call.OutputDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
call.ErrorDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
call.EnableRaisingEvents = true;
call.Exited += new EventHandler(call_Exited);
call.Start();
call.BeginOutputReadLine();
call.BeginErrorReadLine();
call.StandardInput.Close();
call.WaitForExit();
return outData.ToString();
}
private void call_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
outData.Append(e.Data);
}
}
现在当我调用devicesPlus时,有时候我只得到*守护进程没有运行。立即开始* 有一段时间它只是在后台工作而没有结果.. 你能告诉我我的代码中有什么不对,为什么我没有像cmd那样得到正确的回报.. 新来的c#抱歉英语不好......
更新 如果我从我的应用程序外部杀了adb,我会突然得到我软件的回复。
答案 0 :(得分:3)
添加这些行也可以阅读StandardError stream:
psi.Arguments = "start-server";
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
call = Process.Start(psi);
call.OutputDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
call.ErrorDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
call.Exited += new EventHandler(call_Exited);
call.EnableRaisingEvents = true;
call.BeginOutputReadLine();
call.BeginErrorReadLine();
call.StandardInput.Close();
call.WaitForExit();
return outData.ToString();
答案 1 :(得分:3)
WaitForExit()
仅等待进程退出。它不会等待你的进程接收所有输出,所以你有一个竞争条件。
call_OutputDataReceived
调用 e.Data == null
来表示输出的结束。在使用outData.ToString()
之前,您需要等待该通话。
例如,您可以使用new CountdownEvent(2)
等待两个流的结束:
CountdownEvent countdownEvent;
public string devicesPlus()
{
psi.Arguments = "start-server";
countdownEvent = new CountdownEvent(2);
call = Process.Start(psi);
call.OutputDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
call.ErrorDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
call.EnableRaisingEvents = true;
call.Exited += new EventHandler(call_Exited);
call.Start();
call.BeginOutputReadLine();
call.BeginErrorReadLine();
call.StandardInput.Close();
call.WaitForExit();
countdownEvent.Wait();
return outData.ToString();
}
private void call_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
// prevent race condition when data is received form stdout and stderr at the same time
lock (outData)
{
outData.Append(e.Data);
}
}
else
{
// end of stream
countdownEvent.AddCount();
}
}