如何调用命令行程序, 并得到输出, 还有输入交互?

process早就有办法了, 只不过我没有注意.

如调用一个命令行:"cmd /c dir c:\winnt"; 把结果放到一个字符串里.

ProcessStartInfo psi = new ProcessStartInfo("cmd"" /c dir c:\winnt");
psi.RedirectStandardOutput 
= true;
psi.UseShellExecute 
= false;
Process p 
= Process.Start(psi);

output 
= p.StandardOutput.ReadToEnd();
p.WaitForExit();
注意那个waitforexit()一定要放到readtoend之后. MSDN里这样说:


    process组件通过管道与子进程通信。如果子进程写入管道的数据多得足以填满缓冲区,则子进程将一直会阻塞到父进程从管道读取数据时为止。如果应用程序将所有输出读取到标准错误和标准输出,则这会导致死锁。

    意思就是: 如果waitforexit在前, 那么如果数据太多而超出缓冲期大小, 子程序就会等着消费者把数据读出来, 可是这时候由于waitforexit正在阻塞, 做为消费者的过程序readtoend无法执行, 因而导致了死锁.

   除了上面的, 还可以用程序交互:

ProcessStartInfo psi = new ProcessStartInfo("cmd");
psi.RedirectStandardOutput 
= true;
psi.RedirectStandardInput 
= true;
psi.UseShellExecute 
= false;
Process p 
= Process.Start(psi);

p.StandardInput.WriteLine(
@"dir c:\winnt");
p.StandardInput.WriteLine(
@"ver");
p.StandardInput.WriteLine(
@"exit");

output 
= p.StandardOutput.ReadToEnd();
p.WaitForExit();

    重定义了stdin, 执行cmd程序, 进入了命令行交互, 然后向标准输入里写若干个命令, 回车, 有意思, 执行了! 最后千万别忘记了用"exit"命令中断cmd的执行, 不然后面的readtoend时, 永远也不会读到END, 程序又阻塞在这里不会退出. 


    最后, MSDN提到了standarderror, 如果同时重定向了stdout和stderr, 那么不当的方式也会出现死锁: 如:
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();

    MSDN说程序先读了stdout, 完了之后再读stderr, 如果子进程在执行时向stderr写了内容, 那么就会死锁. 我想了一会儿, 没想明白. 如果程序在两个流里都写入了, 那么第一个读stdout的动作完成之前, stderror的内容留着不就行了? 但是没有时间试了.
    MSDN建议用两个线程来处理不同重定向流.  这是个好办法.
posted @ 2005-05-12 16:43 HAL9000 阅读(2364) 评论(2)  编辑 收藏 所属分类: 技术

  回复  引用    
#1楼 2006-02-22 13:25 | hpt321@163.com [未注册用户]
请问,如何在C#中调用TC编写的*.C文件,把*。C文件生成可执行文件,
用指定 TCC -IINCLUDE -LLIB P.C时,
代码如下:
Process ps=new Process();
ps.StartInfo.RedirectStandardInput=true;
ps.StartInfo.RedirectStandardOutput=true;
ps.StartInfo.RedirectStandardError=true;
ps.StartInfo.UseShellExecute=false;
string cur=Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory("d:\\tc\\tc2\\");
ps.StartInfo.FileName="cmd";
ps.Start();

StreamWriter sw=ps.StandardInput;
sw.WriteLine(@"TCC -iinclude -llib p");
sw.WriteLine(@"p.exe");


sw.WriteLine(@"exit");
string output = ps.StandardOutput.ReadToEnd();
string outerr=ps.StandardError.ReadToEnd();
MessageBox.Show(output);
MessageBox.Show(outerr);
Directory.SetCurrentDirectory(cur);
ps.WaitForExit();
ps.Close();




出现如下提示:

Invalid keyboard code specified

请高手指点应该如何来改写.

  回复  引用    
#2楼 2006-03-31 10:31 | GoKu [未注册用户]
请问有没办法隐藏命令行窗口?

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: