在Windows NT中,Windows控制台可以处理Unicode,但是,默认情况下,当输出从命令重定向到文件时,它会转换为当前的ANSI代码页,这意味着代码页外的任何字符都将转换为“? “字符。
可以通过使用/u
开关启动控制台来解决此问题。
我的程序在控制台内运行,如何在控制台启动时检测是否使用了/ u开关?
答案 0 :(得分:1)
据我所知,没有可用于查询此API的API。
为了检测它,我建议在CreateFile
上CONOUT$
,写一些在同一个代码页中不存在的unicode字符(例如日语,中文,希腊语),然后阅读控制台使用ReadConsoleOutputCharacter
寻找有效的unicode或垃圾。然后清理输出(可能先将其复制,然后再恢复)。
这是一种kludge,我还没有实施它来测试,但理论认为它应该有效。
答案 1 :(得分:1)
这是/ U开关的文档:
/ U使内部命令输出到管道或文件为Unicode
很明显,此开关仅影响cmd.exe本身解释的命令的行为。在内部,它可能只是设置了一些标志。无法从外部流程中读取该值。
我认为最好的办法是尝试检索启动cmd.exe实例的命令行。这不是推荐的实践,但在您的情况下应该是安全的。这篇文章解释了如何,但请确保您理解这些警告。
How do I get the command line of another process?
您可以使用GetConsoleProcessList()查找托管cmd.exe进程。
答案 2 :(得分:1)
/u
选项控制命令解释程序的行为,与控制台无关。这个问题,实际上是对它的一些评论,正在犯这样一个经典的错误,就是之前做过很多次,将控制台与一个命令解释器混为一谈。是使用该控制台的进程之一。 A command interpreter is not a console。使命令解释器(或实际上任何其他程序)以某种方式写入其输出的选项与该输出可能或可能不被引导的控制台没有任何关系。
实际上,这些选项甚至与控制台无关。 /U
的{{1}}和/A
选项在命令解释器本身内部翻转内部切换,在编写之前由内置命令(例如CMD
)检查管道和文件。切换的状态决定了他们如何选择编写输出。甚至可以在Reactos DIR
的源代码中看到此选项。切换为bUnicodeOutput
,并由ConWrite()
函数检查。
这当然表明了如何在自己的程序中实现这一目标以达到同样的效果。一个给出一个程序CMD
和/U
(或其他名称)选项,相应地翻转切换,并在发现它正在写入管道或文件时修改一个程序的写入行为。换句话说:一个人正是/A
所做的。用户运行一个程序,将CMD
和/U
选项传递给它,就像他们使用/A
时一样。
换句话说:这种机制的一个例子已经存在。只需复制它。