为什么Process.StandardOutput与实际输出不同和/或不完整?

时间:2018-07-31 22:04:36

标签: c# process stdout psexec

首先,从C#执行PsExec命令时,由于某种原因,输出的一部分在StandardOutput中,而另一部分在StandardError in other posts中提到,但这没什么大不了的。

现在,问题是:即使将两个部分组合在一起,与“命令提示符”窗口中显示的内容相比,“输出”也不完全相同。有时是不同的,有时是不完整的。

这是我的代码:

string args = $@"{computerName} -u ""{username}"" -p ""{password}"" {pathOrCommand}";
var pi = new ProcessStartInfo("PsExec.exe", args);
pi.CreateNoWindow = true;
pi.WindowStyle = ProcessWindowStyle.Hidden;
pi.UseShellExecute = false;
pi.RedirectStandardOutput = true;
pi.RedirectStandardError = true;
using (Process p = Process.Start(pi))
{
    var resultLines = new List<string>();
    var handler = new DataReceivedEventHandler(delegate (object o, DataReceivedEventArgs e)
    {
        resultLines.Add(e.Data);
    });
    p.ErrorDataReceived += handler;
    p.OutputDataReceived += handler;
    p.BeginErrorReadLine();
    p.BeginOutputReadLine();

    p.WaitForExit();   
    string result = string.Join("\r\n", resultLines);
}
  • 不同之处的示例:

    当输入错误的用户名或密码时,命令提示符将显示以下消息: *

      

    登录失败:用户名未知或密码错误。

    ..而上述代码的输出将是:

      

    句柄无效。

  • 一个不完整的示例(这很重要)

    执行此命令PsExec \\computer -u username -p password query session时,结果如下所示: *

     SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
    >services                                    0  Disc
     console           someUserName              1  Active
     rdp-tcp                                 65537  Listen
    

    ..但是从C#执行时的输出仅为:

     SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
    

所以,我的问题是:

  • Process.StandardOutput / Process.StandardError为什么与实际输出不同?

  • 有什么解决办法吗?


* 我只在这里展示输出的相关部分。

1 个答案:

答案 0 :(得分:0)

我仍然不明白为什么输出会有所不同,但是我设法创建了一种解决方法,除非有人提供更好的解决方案,否则我将使用该解决方法。

我使用cmd.exestdoutstderr重定向到临时文件。该过程退出后,我读取了文件的内容,然后将其删除:

string tempFile = Path.GetTempFileName();
string args = $@"/c PsExec.exe {computerName} -u ""{username}"" -p ""{password}"" {pathOrCommand}";
var pi = new ProcessStartInfo("cmd.exe", $"{args} 1> {tempFile} 2>&1");
pi.CreateNoWindow = true;
pi.WindowStyle = ProcessWindowStyle.Hidden;
using (Process p = Process.Start(pi))
{
    p.WaitForExit();

    string result = File.ReadAllText(tempFile);
    File.Delete(tempFile);
}

希望这可以帮助其他有相同问题的人。