Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C#捕获cmd执行plink的所有(stdout、stderr和CON)输出(std out+;err ok,CON不工作)_C#_Shell_Redirect_Console_Capture - Fatal编程技术网

用C#捕获cmd执行plink的所有(stdout、stderr和CON)输出(std out+;err ok,CON不工作)

用C#捕获cmd执行plink的所有(stdout、stderr和CON)输出(std out+;err ok,CON不工作),c#,shell,redirect,console,capture,C#,Shell,Redirect,Console,Capture,我想通过打开进程并运行plink从c#打开SSH连接。应收集所有输出,根据结果,程序将向ssh启动操作。 我最大的问题是,我使用了两个不同的脚本,我需要(自动)的用户交互。因此,我必须捕获所有输出数据(标准输出、标准错误和控制台) 查看以下测试批次应使情况更加清楚: 1: @ECHO OFF 2: ECHO StdOut 3: ECHO StdErr 1>&2 4: ECHO Cons>CON 代码如下: Process process; Process process;

我想通过打开进程并运行plink从c#打开SSH连接。应收集所有输出,根据结果,程序将向ssh启动操作。 我最大的问题是,我使用了两个不同的脚本,我需要(自动)的用户交互。因此,我必须捕获所有输出数据(标准输出、标准错误和控制台)

查看以下测试批次应使情况更加清楚:

1: @ECHO OFF
2: ECHO StdOut
3: ECHO StdErr 1>&2
4: ECHO Cons>CON
代码如下:

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;
[...]
我能够捕获第2+3行,但不能捕获第4行(某些程序使用)。 我也尝试过用powershell(或直接plink)代替cmd.exe作为起点,但结果相同


在c#中是否有任何方法也可以捕获控制台,或者您是否知道任何第三方命令行能够将CON out重定向到stdout或类似的东西?

我甚至不确定这是否可行-至少不使用简单的API

请注意,我在网上没有发现(尽管我尝试过)任何直接证实这一点的信息,但我是这样得出这个结论的

Windows中的控制台是它自己的子系统,由
csrss.exe
管理(从Windows Vista开始也是
conhost.exe
,但我离题了)。它有自己的API集(
AttachConsole
WriteConsole
,等等),每个进程只能有一个“控制台”

另一方面,
CMD.EXE
只是另一个控制台模式的应用程序,它恰好使用控制台并在控制台窗口中启动。您可以通过启动不同的控制台模式应用程序并在process Explorer中查看进程树来观察这种效果:没有CMD.EXE父进程(而是Explorer或您用来启动它的任何程序,当然包括CMD.EXE)

到目前为止,我试图说明“控制台”和
CMD.EXE
、批处理文件或控制台模式应用程序之间的区别

因此,在
CMD.EXE
中使用
>CON
时,实际上会产生与在本机应用程序中写入
CONOUT$
相同的效果(或在类UNIX操作系统上写入
/dev/console
)。在本机应用程序中,托管代码似乎没有直接的等价物,比如
Console.Out
Console.Error
equal
stdout
stderr
(或者
1
2
作为
CMD.EXE
中的文件描述符)

综上所述,当您启动一个进程时,您只能重定向它的标准输出和标准错误流,而不能(本质上)重定向它写入控制台的消息(或
CONOUT$
handle)。我想这与尝试重定向进程写入某个文件的输出是一样的,这(一般)也是不可能的

您可以通过在子进程中使用一些钩子或注入内容来获取控制台输出来实现这一点


不容易做到这一点,也是编写完整的终端(即控制台窗口,而不是
CMD.EXE
!)替换Windows不容易的原因之一,需要一些黑客或变通方法。

以下是一些代码工程项目,它们可以做到这一点(通过本机代码),哪个AFAICT更好地处理重定向所有控制台输出:

此外,该命令允许程序重定向其流。但是,如果一个程序执行显式WriteConsole(),我不确定是否可以重定向它。

AFAIK know your want(重定向CON)只能通过挂钩/注入实现,这相当复杂,基本上不需要执行SSH

对于SSH,您可以使用任意数量的C#库(免费和商业):

  • (商业)
  • (免费)
  • (免费)
  • (商业)
  • (商业)
使用库的主要优点是,您对SSH会话的控制比通过重定向控制台实现的要大得多,而且实现起来更容易

更新-根据评论:


要从远程运行的程序中获得所有输出,您需要使用一个库,该库附带一个SSH的“交互式/终端”类-例如,at的库附带了这样一个类,并且工作非常好(没有关联,只是一个满意的客户),它可以用作纯代码组件或可视控件(任何适合您需要的).

标准输出和控制台之间有什么区别?@DanielHilgarth我不完全确定Windows,但在UNIX上,标准输出将指向任何地方(包括文件或任何地方),而另一个总是指向(文本模式)控制台。这表明,例如,如果您远程登录。控制台输出总是发送到物理控制台/计算机(我认为也有一些选项可以更改,但一般来说)。+1“更容易实现…”并且可能更健壮。已经尝试过SharpSSH,但也只支持std和err out,而不支持console out。将测试sshnet,但不是真正的乐观主义(稍后将告诉您结果)。“不必要”取决于所需的材料。我需要一个程序来自动在带有控制台“gui”的程序中进行用户交互,该程序只写入屏幕,而不写入流。@Yahia:我需要远程运行的程序的输出。最后,这意味着我需要与在cmd.exe提示符(“我在windows中看到的”)上使用plink,然后在此ssh中进行交互相同的输出session@MichaelK. 见上面我的更新。最后我管理了我需要的,关键字“终端”成功了。提供了一个ssh终端并添加了一些代码,从而可以捕获整个屏幕的输出。非常感谢你详细的回答,让我找到了正确的方向!这些节目也只是表演