我有《反恐精英:零点行动》游戏。每当我将其安装在类似文件夹中C:\FolderName
并在安装后启动游戏时,游戏都会以2 个介绍视频 (我在游戏安装文件夹中找到了这些视频,它们都带有 .avi 扩展名)。
但我注意到一个相当奇怪的现象。如果我删除游戏并再次安装,C:\Folder Name
游戏运行正常,只是启动时不会播放那 2 个介绍视频。相当奇怪。
为了确认这是否是确切的原因,我尝试了至少 15 次使用不同名称的文件夹安装此游戏。一些文件夹名称带有空格,一些不带空格。并且它证实如果文件夹名称有任何空格,这些介绍视频将无法播放。
这些视频文件有此路径:C:\My Folder Name\czero\media
或C:\MyFolderName\czero\media
游戏启动hl.exe
文件有路径:C:\My Folder Name
或C:\MyFolderName
在两种情况下游戏都可以正确安装,但视频仅在第二种情况下播放MyFolderName
。
看起来无论是游戏尝试为避免 .avi 文件或某些 Windows 功能强制游戏不播放这些文件 - 只要文件夹名称中有空格。
我会在游戏 SE 网络上询问这个问题,但我强烈地感觉到这种奇怪的行为只是因为主文件夹名称中的空间并且仅与那些 .avi 文件有关。
有什么特别的原因吗?是因为某些防火墙/防病毒/UAC 保护和规则吗?
答案1
听起来像是游戏中的一个错误,代码打开视频时没有使用引号,因此视频路径的一部分被假定为参数,而实际上并非如此,从而导致错误,因此视频永远不会播放。控制台可能也会记录错误。
稍微解释一下……在 Windows 中,当您使用路径时,您可以这样输入:
C:\My_Path_without_spaces
或者
"C:\My Path With Spaces"
注意引号。
当您启动外部程序(例如视频播放器)时,视频播放器可能有如下参数列表(这是示例)
C:\Games\HalfLife\bin\videoplayer.exe /video C:\Games\HalfLife\intro.avi
^ path to videoplayer
^parameter video
^video file
现在假设你的文件夹名称是“Half Life”:
C:\Games\Half Life\bin\videoplayer.exe /video C:\Games\Half Life\intro.avi
^ path to videoplayer (the space may break here too)
^parameter video
^video file
^invalid parameter
没有名为 Half 且不带扩展名的视频,也没有将 Life\intro.avi 理解为参数,因为视频播放器无法识别它。
请注意,HalfLife 1 是一款非常古老的游戏。当时 8.3 长度的文件名仍然很常见。
答案2
根本问题是在 Windows 下被调用者负责解析命令行。按照惯例,被调用的程序期望并获取整个命令行作为一个字符串来自命令 shell。(相比之下,为 *nix 系列操作系统编写的程序需要一组单个参数,对应于argv
*nix shell 通过解析命令行执行的作业。分离参数对于被调用程序来说根本不是问题。)
按照惯例,DOS/Windows 程序将命令行参数视为由空格分隔的“单词”;因此,如果调用者想要传递包含空格的单个参数(例如带有空格的愚蠢路径),则必须用引号引起来。引号是被调用程序看到的命令行的一部分!有关讨论,请参阅这篇微软文章。还有一个附带问题,根本无法保证被调用者能够处理引号!不要随意引用参数。
在您的案例中,忘记引用路径参数:游戏中的一个错误。此外,模块测试中遗漏了一个完整的等价组。
你可能在你最喜欢的 *nix shell 中遇到过这样的麻烦:我如何再次传递包含引号的参数?用户外壳是 *nix 世界中唯一需要解析命令行的程序。相比之下,以编程方式从一个二进制文件调用另一个二进制文件则不存在这个问题:呼叫者,召集者只是在调用之前填充一个参数数组exec
,将单个参数直接提供给被调用者。
正是这种错误的结合,将错误的传统 DOS 调用约定与错误的嬉皮士观念 (都是苹果的错!1 ) 和路径名中的空格混为一谈,导致了像您这样的错误。
1是的,我知道,在苹果采用之前路径名中就已经存在空格(和其他奇怪的字符);但没有一个理智的 *nix 用户会主动将文件夹命名为“Program Files”。这种无稽之谈不应该存在于最终用户系统中。