我的问题似乎是一个直截了当的问题,因为之前曾多次被问过。无论如何,我认为我的情况完全不同,我无法找到任何直觉。我有一个从汇编语言编写的代码编译的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
命令是exe文件路径, args 是传递给exe文件的参数(请注意,此exe不需要参数)
输出始终等于“”!当我使用命令提示符运行exe时,控制台输出肯定不是空的。这就是我得到的:
我还尝试使用python捕获控制台输出,但返回的字符串是awlays empty。
我已经多次这样做但是exe文件是用C#而不是汇编语言编写的,但我认为不应该存在任何差异。
修改
到目前为止尝试的解决方案并由斧头提出:
答案 0 :(得分:1)
您的C#代码是正确的。捕获控制台进程输出的标准方法是通过将进程对象的StartInfo.RedirectStandardOutput
属性设置为true
来重定向标准输出,如here所述。这正是你所做的。
问题,如correctly diagnosed by rkhb,是您在辅助流程中使用Irvine32库,其dumpregs
的实现调用Win32 WriteConsole
function,这不可能是重定向。如果您尝试将标准输出(例如,重定向到管道或文件),则WriteConsole
将失败并显示ERROR_INVALID_HANDLE
,documented on MSDN:
ReadConsole
和WriteConsole
只能用于控制台句柄;ReadFile
和WriteFile
可以与其他句柄(例如文件或管道)一起使用。ReadConsole
和WriteConsole
如果与已重定向且不再是控制台句柄的标准句柄一起使用,则会失败。
与rkhb的评论一样,除了文档之外,这也暗示了解决方案。要支持重定向,您需要更改dumpregs
的实现,以便调用WriteFile
而不是WriteConsole
。这是一个更通用的函数,可以写入任何类型的句柄,包括标准控制台输出( a la WriteConsole
)或您可以将输出重定向到的任何其他类型的对象。一旦你做了这个改变,你当然需要重建Irvine32库。
WriteFile
的唯一重要限制是它不支持WriteConsole
之类的Unicode输出,但在您的情况下这不是问题。 dumpregs
的输出都是ANSI。