【问题标题】:Empty standard output when run an exe file using C#使用 C# 运行 exe 文件时为空标准输出
【发布时间】:2017-06-15 19:21:37
【问题描述】:

我的问题可能看起来很直截了当,因为它以前被问过很多次。无论如何,我认为我的情况完全不同,我找不到任何直觉。我有一个用汇编语言编写的代码编译的 exe 文件,我想使用另一个代码运行这个 exe 并捕获它的输出。我是用 C# 做的,这里是它的代码:

static string runCommand(string command, string args)
    {
        if (File.Exists(command))
        {
            Process p = new Process();
            p.StartInfo.FileName = command;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.Arguments = args;
            p.Start();
            p.WaitForExit();
            string output = p.StandardOutput.ReadToEnd();
            return output; 
        }
        return "";
    }

目标 exe 文件的代码非常简单(我使用的是 Irvine 库):

INCLUDE Irvine32.inc


.data

.code
main proc
    call dumpregs
    exit
main ENDP

end main

其中command是exe文件路径,args是传给exe文件的参数(注意这个exe不需要参数)

输出总是等于 "" !。当我使用命令提示符运行exe时,控制台输出肯定不是空的。这是我得到的:

我也尝试使用 python 捕获控制台输出,但返回的字符串是空的。

我已经做过几次了,但是exe文件是用C#而不是汇编语言编写的,但我认为应该没有任何区别。

编辑

迄今为止尝试的解决方案并由斧头建议:

  1. Capturing console output from a .NET application (C#)
  2. How to spawn a process and capture its STDOUT in .NET? [duplicate]
  3. Process.start: how to get the output?

它们都不适合我

如果您需要任何进一步的信息,请在 cmets 中告诉我

【问题讨论】:

  • @hatchet 谢谢先生的评论。我的问题不在于如何使用 C# 运行 exe 文件,我已经有了这方面的代码。我的问题是输出总是一个空字符串
  • @hatchet 没有一个对我有用。输出总是空的
  • 你确定输出是标准输出而不是标准错误?
  • Irvine 的库与无法重定向的 WriteConsole 一起使用。你要把Irvine32.asm里面的改成WriteFile,组装起来和floatio.obj一起建一个新的库。
  • 其他cmets都是正确的。问题不在您的 c# 代码中。如果该程序(调用 dumpregs)已正常写入标准输出,那么您的代码将捕获它。我进行了快速测试以验证这一点。

标签: c# assembly process exe command-prompt


【解决方案1】:

您的 C# 代码是正确的。捕获控制台进程输出的标准方法是通过将进程对象的StartInfo.RedirectStandardOutput 属性设置为true 来重定向标准输出,如here 所述。这正是你所做的。

问题,如correctly diagnosed by rkhb,是你在辅助进程中使用了Irvine32库,其dumpregs的实现调用了Win32的WriteConsole function,无法重定向。如果您尝试将标准输出重定向(例如,到管道或文件),则WriteConsole 将失败并显示ERROR_INVALID_HANDLE,如documented on MSDN

ReadConsoleWriteConsole 只能与控制台句柄一起使用; ReadFileWriteFile 可以与其他句柄(例如文件或管道)一起使用。如果与已重定向且不再是控制台句柄的标准句柄一起使用,ReadConsoleWriteConsole 将失败。

就像 rkhb 的评论一样,除了文档之外,这也暗示了解决方案。要支持重定向,您需要将dumpregs 的实现更改为调用WriteFile 而不是WriteConsole。这是一个更通用的函数,可以写入 any 类型的句柄,包括标准控制台输出 (a la WriteConsole) any您可能会将输出重定向到的其他类型的对象。完成此更改后,您当然需要重建 Irvine32 库。

WriteFile 的唯一重要限制是它不支持像 WriteConsole 那样的 Unicode 输出,但在您的情况下这不是问题。 dumpregs 的输出都是ANSI。

【讨论】:

  • 你是绝对正确的!我使用 WriteFile 程序在控制台屏幕上打印。现在我可以使用 C# 代码捕获输出。非常感谢先生! @rkhb 也谢谢你先生!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
  • 2019-12-25
  • 2020-02-28
  • 1970-01-01
相关资源
最近更新 更多