我正在构建一个 Win32 GUI 应用程序。在该应用程序中,我使用了一个打算在命令行应用程序中使用的 DLL。
假设 Foo.exe 是我的 GUI 应用程序,bar() 是 DLL 中的一个函数,它将“hello”打印到标准输出。Foo.exe 调用 bar()。
如果我使用重定向(>)(即)从命令行运行 Foo.exe,Foo.exe > out.txt
它会将“hello”写入 out.txt 并正常退出(如预期的那样)。
但是,如果我在没有重定向的情况下运行 Foo.exe (从 cmd.exe 或通过在 Windows 资源管理器中双击),它会在调用 bar() 时崩溃。
如果我在调试器中使用命令行中的重定向运行 Foo.exe (通过 VS 的项目属性设置)并调用“GetStdHandle(STD_OUTPUT_HANDLE)”,我会得到一个合理的句柄地址。如果我在命令行中没有重定向就调用它,我得到 0。
我需要一些东西来“初始化”标准吗?有没有办法可以在应用程序启动中设置此重定向?(重定向到一个文件将是理想的。但只需丢弃 DLL 打印的数据也可以。)
最后,我怀疑 DLL 是通过 CRT POSIX-like API 写入标准输出的,因为它是一个跨平台的 DLL。我不知道这是否重要。
我尝试使用 CreateFile 创建文件并调用 SetStdHandle,但这似乎不起作用。但是,我可能错误地创建了文件。请参阅下面的代码。
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
// hStdOut is zero
HANDLE hFile;
hFile = CreateFile(TEXT("something.txt"), // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_NEW, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
BOOL r = SetStdHandle(STD_OUTPUT_HANDLE, hFile) ;
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
// hStdOut is now equal to hFile, and r is 1
bar();
// crashes if there isn't a redirect in the program arguments
更新:我刚刚找到这篇文章: http: //support.microsoft.com/kb/105305。它指出“请注意,此代码无法纠正句柄 0、1 和 2 的问题。事实上,由于其他复杂性,无法纠正此问题,因此有必要使用流 I/O 而不是低- 级 I/O。”
我的 DLL 肯定使用文件句柄 0,1 和 2。所以,这个问题可能没有好的解决方案。
我正在研究一种检查这种情况的解决方案,并使用 CreateProcess 适当地重新启动 exe。完成后我会在这里发布。