Mic*_* K. 7 c# shell console redirect capture
我想通过打开一个进程并运行plink来打开来自c#的SSH连接.应收集所有输出,并根据结果,程序将触发对ssh的操作.我的大问题是,我正在使用一对,如果不同的脚本,我需要(自动)用户交互.因此,我必须捕获所有输出数据(标准输出,标准错误和CONSOLE).
查看以下测试批次应该使案例更加清晰:
1: @ECHO OFF
2: ECHO StdOut
3: ECHO StdErr 1>&2
4: ECHO Cons>CON
Run Code Online (Sandbox Code Playgroud)
代码如下:
Process process;
Process process;
process = new Process();
process.StartInfo.FileName = @"cmd.exe";
process.StartInfo.Arguments = "/c test.bat";
process.StartInfo.UseShellExecute = false;
process.StartInfo.ErrorDialog = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
StreamWriter inputWriter = process.StandardInput;
[...]
Run Code Online (Sandbox Code Playgroud)
我能够捕获2 + 3行,但不能捕获4行(某些程序使用).我也试过powershell(或直接plink)而不是cmd.exe作为起点,但结果相同.
在c#中是否有任何方法可以捕获控制台,或者您是否知道任何第三方命令行能够将CON重定向到stdout或类似的东西?
我不确定这是否可能 - 至少不使用一些简单的简单API.
请注意,我没有找到(虽然我尝试过)网上直接确认的任何信息,但这是我得出这个结论的方式.
Windows中的控制台是它自己的子系统,由csrss.exe(也从Windows Vista开始conhost.exe,但我离题)管理.它有自己的API(AttachConsole,WriteConsole等),每个进程只能有一个"控制台".
CMD.EXE另一方面,它只是另一个控制台模式应用程序,恰好使用控制台并将其启动为控制台窗口.你可以通过启动一个不同的控制台模式应用程序来观察这种效果,并在例如Process Explorer中观察进程树:没有CMD.EXE父进程(而是它是资源管理器或你用来启动它的任何东西 - 当然包括CMD.可执行程序).
到目前为止,我试图CMD.EXE通常显示"控制台"和批处理文件或控制台模式应用程序之间的区别.
因此,当CMD.EXE您使用时,> CON实际上会产生与CONOUT$在本机应用程序中执行写入(或/dev/console在类UNIX操作系统上的典型写入)相同的效果.似乎没有成为一个直接等效托管代码,Console.Out并且Console.Error平等stdout和stderr在本机应用程序(或1和2文件描述符中CMD.EXE).
说了这么多,当你启动一个进程时,你只能重定向它的标准输出和标准错误流,但不能(本身)它写入控制台(或CONOUT$句柄)的消息.我想这与尝试重定向进程写入某个文件的输出相同,这也不是(一般)可能的.
您可以通过在子进程内部使用某些钩子或注入来获取控制台输出来实现此目的.
不能轻易做到这一点,也是(其中一个)为什么编写一个完整的终端(即控制台窗口,而不是CMD.EXE!)替换Windows的原因并不容易,并且需要一些黑客或解决方法.
AFAIK 知道你想要什么(重定向 CON)只能通过挂钩/注入来实现,这是相当复杂的,并且基本上不需要执行 SSH。
对于 SSH,您可以使用任意数量的 C# 库(免费和商业):
使用库的主要优点是,与通过某些重定向控制台相比,您可以更好地控制 SSH 会话,并且更容易实现......
更新 - 根据评论:
要从远程运行的程序获取所有输出,您需要使用一个带有 SSH 的“交互式/终端”类的库 - 例如http://www.rebex.net/ssh-pack/default.aspx上的库带有这样一个类并且工作得很好(没有附属关系,只是一个满意的客户),它可以用作仅代码组件或可视控件(无论适合您的需求)。