2

当我使用 ruby​​ 打印出 windows 7 system32 目录中的所有文件时,一些文件丢失了。我使用这个简单的目录迭代:

Dir.foreach("C:\\Windows\\System32") do |fname|
  puts fname
end

我正在专门寻找 python27.dll,虽然它存在,但它没有打印出来。文件已存在?似乎与 dir 迭代有相同的问题。它为现有文件返回 false:

File.exists? "C:\\Windows\\System32\\python27.dll" #returns false

检查文件夹的另一个现有文件有效:

File.exists? "C:\\Windows\\System32\\quartz.dll" #returns true

但是如果我复制现有文件或在 system32 中创建一个新文件,它就不起作用

File.exists? "C:\\Windows\\System32\\quartz2.dll" #returns false

此外,将 python27.dll 复制到另一个目录并检查是否存在有效:

File.exists? "C:\\Otherfolder\\python27.dll" #returns true

该问题与字母大小写或路径分隔符无关。我检查了那个。此外,我看不到有效文件和无效文件的用户权限存在差异......

我真的不知道,为什么会发生这种情况......谁能重现这个???

谢谢

[编辑]

花了一段时间,但我找到了答案。

这是一个 32/64 位问题。对于 ruby​​ 作为 32 位应用程序,“C:\Windows\System32”实际上是“C:\Windows\SysWOW64”。正如 64 位 WinExplorer 显示的那样,python27.dll 位于 System32 中(只有 64 位进程可以看到 - 好吧,令人困惑),而它应该在 SysWOW64 中才能看到。安装 32 位版本的 Python 为我解决了这个问题(因为我无法更改 ruby​​ 脚本,因为它是 ruby​​python 的一部分)。

4

3 回答 3

3

在 Windows 7(实际上是 Vista)中,许多在早期版本的 Windows 中仅存在于纸面上的安全策略现在实际上由操作系统强制执行。例如,根据微软的文档,几十年来写信几乎是非法的C:\Windows\System32,但如果你真的尝试过,它仍然有效。不再。从 Vista 开始,C:\Windows\System32是禁止访问的。

但是,为了不破坏现有(损坏的)应用程序,Microsoft 引入了文件系统虚拟化。如果应用程序尝试写入C:\Windows\System32,它会被静默重定向到C:\Users\%Username%\AppData\Local\VirtualStore\Windows\System32. 因此,这个特定的应用程序可以看到它创建或更改的所有文件C:\Windows\System32,但其他应用程序只能看到未更改的/空目录。

这不仅适用于C:\Windows\System32其他系统目录,也适用于其他系统目录。此外,它适用于注册表的系统部分,HKEY_LOCAL_MACHINE例如。

这种虚拟化是针对每个应用程序的。即,如果应用程序 A 试图在受保护的目录中创建或修改文件,Windows 将拦截该调用并将其重定向到 VirtualStore。它还会在某处记录此重定向。现在,当同一个应用程序 A 再次尝试查看该位置时,Windows 将使用记录的重定向,以便应用程序认为文件就在它放置的位置,而事实上,它完全在其他位置。

但是,如果另一个应用程序 B 查看该目录,则不会触发重定向,并且 B 只会看到一个原始系统目录。这就是重点:在过去,不同的应用程序会通过覆盖彼此在系统目录中的文件来创建各种奇怪的错误。即,一个应用程序将其转储python27.dllC:\Windows\System32另一个应用程序将转储自己的,略有不同的不兼容版本python27.dll,覆盖第一个。

因此,您使用了一个应用程序将 DLL 复制到那里(可能explorer.exe),而您使用了另一个应用程序,即ruby.exe查看它。但explorer.exe实际上并没有将其复制到system32中,而是重定向到了 VirtualStore。当你使用explorer.exe时,重定向会被触发,你会在你认为放置它的地方看到文件,但是当你使用时ruby.exe,重定向不会触发,它会看到实际的目录。

敢打赌_

File.exists? "C:/Users/#{ENV['Username']}/AppData/Local/VirtualStore/Windows/System32/python27.dll"

返回true

于 2012-08-25T14:15:17.557 回答
2

您确定这些文件在 中可用C:\\Windows\\System32\\吗?

我从 -folder 中不知道这个问题System32,但我在 -folder 中遇到了一些像你这样的问题Program Files

如果您尝试将数据保存在某些系统文件夹中并且您不是管理员,Win7 不会将其存储在该位置,而是在用户特定的虚拟存储中。当您查看系统文件夹时,虚拟存储中的文件也会显示在那里。但路径是另一条路。

您可以在任何地方检查您的虚拟商店c:\users\<username>\Appdata\local\Virtual Store\(至少程序文件夹在那里)。

于 2012-08-25T14:10:29.847 回答
0

我遇到了同样的问题,事实证明,当使用超过 260 个符号的路径时,ruby 会表现得这样:

  Administrator@WIN-NUMKGBH6IIM ~
  $ mkdir -p /cygdrive/c/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/

  Administrator@WIN-NUMKGBH6IIM ~
  $ /cygdrive/c/opscode/chef/embedded/bin/ruby <<'EOF'
  puts File.exists?("C:/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/")
  EOF

  true

  Administrator@WIN-NUMKGBH6IIM ~
  $ /cygdrive/c/opscode/chef/embedded/bin/ruby <<'EOF'
  puts File.exists?("C:/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/")
  EOF

  false
于 2014-06-27T11:08:46.680 回答