我制作了一个在.NET Framework 4.0上运行的WinForms应用程序。在调用(一次在启动时)Win32 API函数Console.WriteLine()
之后,它使用AttachConsole(-1)
方法在父控制台上进行写操作。
只要我只需要在屏幕上显示输出,它就可以完美地工作。不幸的是,当我使用带有管道重定向操作符的批处理时,如下所示:
application.exe > output.txt
它只是创建一个空文件。也许有一些问题与我使用
AttachConsole
时要解决的实际管道有关?为什么命令提示符无法捕获数据并将其放在文件上?有人知道与这种情况有关的任何问题吗? 最佳答案
Console.Out
延迟初始化。首次引用它时,运行时将调用GetStdHandle(STD_OUTPUT_HANDLE)
以获取标准输出句柄。如果此调用在对AttachConsole
的调用之前发生,则将获取文件的句柄以进行重定向。如果此调用之后发生,您将获得控制台输出句柄。
下列类修正了标准输出和错误句柄。如果您从控制台启动应用程序,您会注意到在下一个提示后会出现任何输出。您可以使用start /wait
避免这种情况。
using System;
using System.Runtime.InteropServices;
namespace SomeProject
{
class GuiRedirect
{
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool AttachConsole(int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(StandardHandle nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetStdHandle(StandardHandle nStdHandle, IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern FileType GetFileType(IntPtr handle);
private enum StandardHandle : uint
{
Input = unchecked((uint)-10),
Output = unchecked((uint)-11),
Error = unchecked((uint)-12)
}
private enum FileType : uint
{
Unknown = 0x0000,
Disk = 0x0001,
Char = 0x0002,
Pipe = 0x0003
}
private static bool IsRedirected(IntPtr handle)
{
FileType fileType = GetFileType(handle);
return (fileType == FileType.Disk) || (fileType == FileType.Pipe);
}
public static void Redirect()
{
if (IsRedirected(GetStdHandle(StandardHandle.Output)))
{
var initialiseOut = Console.Out;
}
bool errorRedirected = IsRedirected(GetStdHandle(StandardHandle.Error));
if (errorRedirected)
{
var initialiseError = Console.Error;
}
AttachConsole(-1);
if (!errorRedirected)
SetStdHandle(StandardHandle.Error, GetStdHandle(StandardHandle.Output));
}
}
}
关于.net - AttachConsole()在管道上显示数据,但>运算符未正确重定向到文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11523595/