是否有可能以某种方式更改Windows上的标准I/O功能句柄?提供的语言是C++。如果我理解正确,通过选择控制台项目,编译器只需为您预先分配控制台,并操作所有标准I/O函数以处理其句柄。所以,我想要做的是让一个控制台应用程序实际写入另一个应用程序控制台缓冲区。虽然我可以获得第一个控制台句柄,但是通过文件将其传递给第二个应用程序(我不太了解进程间通信,而且这看起来很简单),并且以某种方式用于第一个应用程序句柄的prinf。这可以做到吗?我知道如何获得控制台句柄,但我不知道如何将printf重定向到该句柄。它只是为了学习目的而更加了解OS背后的工作。我感兴趣的是printf如何知道它所控制的控制台。更改默认控制台I/O功能句柄
回答
如果我理解你正确,你可以在http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx找到你想写的应用程序的源代码。这个例子展示了如何写stdin
的另一个应用程序,并阅读它的stdout
。
一般理解。编译器不会“为您预先分配控制台”。编译器使用在输出中写入的标准C/C++库。所以,如果你使用例如printf()
下面的代码将在年底执行的样子:
void Output (PCWSTR pszwText, UINT uTextLenght) // uTextLenght is Lenght in charakters
{
DWORD n;
UINT uCodePage = GetOEMCP(); // CP_OEMCP, CP_THREAD_ACP, CP_ACP
PSTR pszText = _alloca (uTextLenght);
// in the console are typically not used UNICODE, so
if (WideCharToMultiByte (uCodePage, 0, pszwText, uTextLenght,
pszText, uTextLenght, NULL, NULL) != (int)uTextLenght)
return;
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), pszText, uTextLenght, &n, NULL);
//_tprintf (TEXT("%.*ls"), uTextLenght, pszText);
//_puttchar();
//fwrite (pszText, sizeof(TCHAR), uTextLenght, stdout);
//_write (
}
所以,如果一个人改变的STD_OUTPUT_HANDLE
的值的所有输出将去一个文件/管材等。如果程序使用WriteConsole
而不是WriteFile
这样的重定向功能不起作用,但标准C/C++库不这样做。
如果您不想从子进程中重定向stdout
,而是从当前进程中直接调用SetStdHandle()
(请参阅http://msdn.microsoft.com/en-us/library/ms686244%28VS.85%29.aspx)。
“控制台分配”做一个操作系统的加载程序。它看起来是二进制EXE文件(IMAGE_OPTIONAL_HEADER
的子系统部分,参见http://msdn.microsoft.com/en-us/library/ms680339%28VS.85%29.aspx),如果EXE在这个地方有3个(IMAGE_SUBSYSTEM_WINDOWS_CUI
),它会使用父进程的控制台或创建一个新进程。可以在CreateProcess
调用的参数中改变一点这种行为(但只有当您在代码中启动子进程时)。您在链接器开关/子系统方面定义的EXE标志(请参阅http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx)。
如果你想printf
重定向到一个手柄(FILE *),只是做
fprintf(handle, "...");
例如复制printf
与fprintf
fprintf(stdout, "...");
或错误报告
fprintf(stderr, "FATAL: %s fails", "smurf");
这也是你写入文件的方式。 fprintf(file, "Blah.");
如果我的理解正确,听起来好像您需要Windows API函数AttachConsole(pid)
,该函数将当前进程附加到PID为pid
的进程所拥有的控制台。
我认为你是对的。 http://msdn.microsoft.com/en-us/library/ms681952%28VS.85%29.aspx – dss539 2010-05-12 21:37:24
- 1. 获取控制台句柄
- 2. 更改默认功能django
- 3. 更改默认控制器
- 4. web2py:更改默认控制器和功能
- 5. 更改功能之前的默认值
- 6. 更改dropzone.js的默认功能性
- 7. Android开发者控制台,更改默认语言
- 8. 如何更改默认的Eclipse控制台?
- 9. 如何更改代码::块默认控制台
- 10. AWS管理控制台 - 从S3更改默认值?
- 11. 启动期间更改默认控制台日志级别
- 12. 更改控制台应用程序的默认设置
- 13. 更改Laravel的默认(根)控制器
- 14. 更改默认控制器actionresult
- 15. Yii 2.0更改默认控制器
- 16. 在功能区控件上更改默认语言
- 17. 使用Symfony2 Doctrine2控制台/生成功能更改表格?
- 18. dataGridView默认错误对话框句柄
- 19. Rails的控制台默认环境
- 20. 更改默认scala平台netbeans?
- 21. 更改gtk.Paar句柄大小
- 22. 更改控制台大小
- 23. Javascript默认功能
- 24. 默认功能 - PHP
- 25. 默认复制构造函数句柄const?
- 26. 如何更改Symfony2 Behat Bundle默认功能上下文文件(FeatureContext.php默认)
- 27. 是否有可能取代Eclipse中的默认控制台?
- 28. 如何更改Firebase控制台网页中的语言默认值?
- 29. 限制(amp)功能的默认参数
- 30. CakePHP默认控制器不改变URL
谢谢。那么,fprintf是可重定向的printf?而且,printf如何知道它是默认的控制台? – 2010-05-13 15:57:37
默认情况下,printf会转到“stdout”引用的任何标准输出。主要是控制台,或者重定向(“yourprogram> output.txt”)重定向的文件。 – LukeN 2010-05-13 16:16:53