使用“C:\Program Files (x86)”时,我遇到了一个奇怪的问题,该问题位于该路径下方的某个程序中。我用测试程序重现了该行为。
int _tmain(int argc, _TCHAR* argv[])
{
wprintf(L"%d\n", argc);
for (int i = 0; i < argc; i++) {
wprintf(L"%s\n", argv[i]);
}
return 0;
}
程序计算并返回所有命令行参数(包括用于识别程序的程序路径)。我把它命名为“HelloWorld.exe”,因为我很赶时间。
对于运行程序的三种可能方式,它给出了两种不同的结果,而我期望的是相同的结果。
当我从它自己的目录运行 HelloWorld.exe 时,输出是
1
HelloWorld.exe
该输出是正确的并且符合预期。
当我从另一个位置运行位于“P:\Test (x86)”中的 HelloWorld.exe 并使用引用的路径时,输出为
1
P:\Test (x86)\HelloWorld.exe
该输出也是正确的并且符合预期。
但是,当我从另一个位置运行 HelloWorld.exe 并使用带有转义空格和括号的路径时,程序找到了(即路径正确),但输出错误:
2
P:\Test
(x86)\HelloWorld.exe
由于某种原因在
中的转义空间P:\测试\^ ^(x86^)\HelloWorld.exe
由于某种原因成为空间读取操作符,Windows 在将路径读取为 one 字符串以查找程序后,在创建该数组之前决定它毕竟是两个字符串然后程序引用。
此行为发生在 Windows XP (x86) 和 Windows Server 2008 R2 (x64) 中。我假设它存在于所有 (NT) 版本的 Windows 中。
最佳答案
更新:
糟糕。也许它是 Windows 中的错误(或者该术语可能是错误的)。
我刚刚制作了一个快速的小测试程序,它只需调用 GetCommandLine()
并将其打印到控制台。
我调用它:
test The^ rain^ in^ Spain^ falls^ mainly^ on^ the^ plain^ ^(or^ so^ they^ say^).
这是输出:
test The rain in Spain falls mainly on the plain (or so they say).
所以我猜运行时库根本看不到插入符号,您唯一的选择是告诉您的用户使用引号而不是转义符。
不,这不是 Windows 中的错误。这是您的 C 运行时库中的错误(尽管在这种情况下我可能更喜欢术语缺点或不足)。
Windows 正在处理转义字符并定位您的可执行文件。但这不是将命令行分隔为参数的原因。 Windows 不是调用您的 main
函数(在本例中为 _tmain
)。它只是在 PE header 中定义的入口点启动您的进程。在这个位置是一些 C 库代码(或对它的动态调用),在其他启动任务中,调用 kernel32 函数 GetCommandLine()
,然后在空格上拆分它,尊重引号,但不是,显然,插入符号逃脱了。
这并不奇怪,真的。我认为大多数人都不知道您可以在 Windows 命令行中使用插入符号转义字符。我当然没有。
如果这给您带来了现实世界的问题,即有人实际上使用插入符号转义来调用您的程序,您可以告诉他们停止,或者编写您自己的命令行解析例程,将输出传递给它GetCommandLine()
,并忽略在 main
中传递给您的内容。
关于windows - 我发现了 Windows 错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12111080/