如果安装路径中有空格,为什么反恐精英:条件零不能在 Windows 中播放介绍视频?

Vik*_*kas 30 video windows windows-10

我有反恐精英:条件零游戏。每当我将其安装在类似文件夹中C:\FolderName并在安装后启动游戏时,游戏都会以2 个介绍视频 开始(我在游戏安装文件夹中找到了这些视频,两者都有 .avi 扩展名)

但是我注意到了一个非常奇怪的行为。如果我在游戏中再次删除并安装游戏,C:\Folder Name则可以正常工作,只是这两个介绍视频在启动时无法播放。很奇怪。

为了确认这是否是确切原因,我尝试了至少 15 次使用不同命名文件夹安装此游戏。很少有文件夹名称有空格,很少有没有空格。并且它确认如果文件夹名称有任何空格,这些介绍视频将不会播放。

这些视频文件具有以下路径:C:\My Folder Name\czero\mediaC:\MyFolderName\czero\media

游戏启动hl.exe文件的路径:C:\My Folder NameC:\MyFolderName

游戏在这两种情况下都能正确安装,但视频只能在第二种情况下播放,即MyFolderName.

看起来游戏试图避免 .avi 文件或某些 Windows 功能强制游戏不播放这些文件 - 只要文件夹名称中有空格。

我会在游戏 SE 网络上询问它,但我强烈觉得这种奇怪的行为只是因为主文件夹名称中有空格并且仅与那些 .avi 文件相关。

有什么特别的原因吗?是不是因为某些防火墙/防病毒/UAC 保护和规则?

LPC*_*hip 51

听起来像是游戏中的一个错误,代码在没有引号的情况下打开视频,因此视频路径的一部分被假定为一个参数,而它实际上不是,从而导致错误,因此视频永远不会播放。控制台也可能会记录错误。

稍微解释一下……在 Windows 中,当您使用路径时,您可以这样输入:

C:\My_Path_without_spaces
Run Code Online (Sandbox Code Playgroud)

或者

"C:\My Path With Spaces"
Run Code Online (Sandbox Code Playgroud)

注意引号。

当您启动外部程序时,例如视频播放器,视频播放器的参数列表可能如下(这是一个示例)

C:\Games\HalfLife\bin\videoplayer.exe /video C:\Games\HalfLife\intro.avi
                      ^ path to videoplayer
                                      ^parameter video
                                             ^video file
Run Code Online (Sandbox Code Playgroud)

现在假设你有半条命作为文件夹名:

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
 
Run Code Online (Sandbox Code Playgroud)

没有没有扩展名的名为 Half 的视频,也没有将 Life\intro.avi 理解为参数,因为视频播放器无法识别它。

请注意,HalfLife 1 是一款非常古老的游戏。在那个时代,8.3 长度的文件名仍然很常见。

  • @Aganju 不在 Windows 中,在 3rd 方程序中。Linux 有同样的“问题”。 (17认同)
  • @Dev 在单个字符串中传递所有参数不是错误而是设计缺陷,这给开发人员带来了几代头痛:[“CommandLineToArgvW 将引号外的空格视为参数分隔符。”](https://docs.microsoft.com /en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw) 嗯。对比 [“在 *nix 上,参数会被任何创建新进程的程序解析。”](https://daviddeley.com/autohotkey/parameters/parameters.htm#LINUXRULES) 没有任何格式化或解析问题(除了用户外壳)。 (9认同)
  • 如果您的用户名中有空格,则许多 Windows 内容都会以奇怪的方式失败。:( (7认同)
  • @ToddSewell 在通过 COMMAND.COM 或 CMD.EXE 路由任意字符串使用组合的旧 Windows 程序中更为普遍。即使在 Linux 的旧时代,人们也知道在他们的 shell 脚本中使用引号,并且执行子进程的程序通常将 argv 作为字符串数组传递,因此他们不必处理 shell 的转义参数。 (4认同)
  • 反馈:我喜欢 [other answer](https://superuser.com/a/1641129/432690) 因为它触及了你的答案遗漏的内容:假设命令 `videoplayer.exe /video C:\Games\Half Life\intro .avi` 通过这样引用来“修复”:`videoplayer.exe /video "C:\Games\Half Life\intro.avi"` 可能*也可能不会*成功;这取决于`videoplayer.exe` 是否支持引用。游戏中存在错误,但这不一定是因为“代码打开没有引号的视频”。*也许* `videoplayer.exe` 一开始就瘫痪了。 (4认同)
  • @Dev 这仍然并不意味着 Windows 有问题。尽管 Windows 平台的更多开发人员很可能会犯这样的错误,只是因为他们不习惯使用命令行。不是因为他们没有那么好(我不会称游戏开发者为糟糕的程序员),而是因为他们并不经常需要这些知识。 (2认同)
  • @Aganju 实际上,任何想在路径中留出空间的人都应该被鞭打和分割。这可能是比 [nullpointer](https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions) 更昂贵的错误。 (2认同)

Pet*_*ica 17

根本问题是在 Windows 下,被调用者负责解析命令行。被调用者将整个命令行作为一个字符串。(相比之下,*nix 系列操作系统将一组单个参数传递给被调用者,对应于argv。分隔参数根本不是问题。)典型的约定用空格分隔命令行参数;因此,必须引用包含空格的单个参数。引号是传递给被调用者的命令行的一部分!有关讨论,请参阅这篇 Microsoft 文章。作为一个附带问题,根本无法保证被调用者处理报价!不要无故引用参数。

在您的情况下,忘记引用路径参数:游戏中的错误。此外,模块测试中的整个等效组也被遗漏了。

您可能从您最喜欢的 *nix shell 中知道这样的麻烦:如何再次传递包含引号的参数?该用户shell是在* nix的世界上唯一的程序,需要解析的命令行。相比之下,以编程方式从另一个二进制文件调用一个二进制文件没有这个问题:调用者只是在exec调用之前填充一个参数数组,在银盘上为被调用者提供单个参数。

正是这种考虑不周的传统 DOS 调用约定与不周全的嬉皮士思想(这是 Apple 的错!1)在路径名中的空格的组合,导致了像您这样的错误。


1是的,我知道,在苹果采用之前,路径名中的空格(和其他有趣的字符)已经存在;但没有理智的 *nix 用户会自愿将文件夹命名为“Program Files”。此类废话无权存在于最终用户系统上。